所以我将自定义 html 模板转换为 vuejs 项目。 我已经导入了主页中要使用的所有 css 和 js 文件。 CSS 文件加载正常。 对于 JS 文件,主题附带了一些自定义 js 脚本以及常用的库,如 Three.js 等。 我将所有这些导入到脚本标记中的 HomeComponent 下方。 但我遇到了这个错误:
"Uncaught TypeError: Cannot read properties of null (reading 'offsetWidth')
at eval (demo3.js?dad6:2:20)
at ./src/assets/assets/js/demo3.js (app.js:92:1)
at __webpack_require__ (app.js:1124:33)
at fn (app.js:1357:21)
at eval (index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/HomeComponent.vue?vue&type=script&lang=js:26:85)
at ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/HomeComponent.vue?vue&type=script&lang=js (app.js:30:1)
at __webpack_require__ (app.js:1124:33)
at fn (app.js:1357:21)
at eval (HomeComponent.vue?vue&type=script&lang=js:5:216)
at ./src/components/HomeComponent.vue?vue&type=script&lang=js (app.js:296:1)"
下面是我的 App.vue 代码:
<template>
<router-view />
</template>
<script>
export default {
name: "App",
components: {},
};
</script>
下面是我的 homecomponent.vue 代码(部分 - 一些代码隐藏在模板内部):
<template>
<header class="offcanvas-menu">
<input type="checkbox" id="toogle-menu" />
<label for="toogle-menu" class="toogle-open"><span></span></label>
<nav>
<div>
<label for="toogle-menu" class="toogle-close">
<span></span>
</label>
</div>
<ul>
<li><a href="#section1">Section </a></li>
<li><a href="#section2">Section </a></li>
<li><a href="#section3">Section </a></li>
<li><a href="#section4">Section </a></li>
<li><a href="#section5">Section </a></li>
</ul>
</nav>
</header>
<main>
<div class="content">
<canvas class="scene scene--full" id="scene"></canvas>
<div class="content__inner">
<h2 class="content__title">مؤشر المعلوماتية</h2>
<div class="content-button mt-2">
<button
type="button"
class="btn btn-relief-primary btn-large menu-trigger display-5"
>
<i data-feather="menu"></i> القائمة
</button>
</div>
</div>
</div>
<nav class="grim">
<div class="grim__item">
<div class="grim__item-bg grim__item-bg--5"></div>
</div>
<div class="grim__item">
<div class="grim__item-bg grim__item-bg--5"></div>
</div>
<div class="grim__item">
<div class="grim__item-bg grim__item-bg--5"></div>
<div class="grim__item-content">
<div class="grim__item-inner"></div>
</div>
</div>
..
<div class="grim__item">
<div class="grim__item-bg grim__item-bg--9"></div>
<div class="grim__item-img grim__item-img--4"></div>
<a href="dashboard-region.html" class="grim__link grim__item-content">
<div class="grim__item-inner">
<h3 class="grim__item-title">test</h3>
<span class="grim__item-desc">test</span>
</div>
</a>
<div class="grim__item-bg grim__item-bg-cover grim__item-bg--9"></div>
</div>
<div class="grim__item">
<div class="grim__item-bg grim__item-bg--10"></div>
<div class="grim__item-img grim__item-img--5" style=""></div>
<a href="wizard.html" class="grim__link grim__item-content">
<div class="grim__item-inner">
<h3 class="grim__item-title">test</h3>
<span class="grim__item-desc"
>test</span
>
</div>
</a>
<div class="grim__item-bg grim__item-bg-cover grim__item-bg--10"></div>
</div>
</nav>
</main>
<!-- home -->
</template>
<style>
@import url("https://fonts.googleapis.com/css?family=Barlow:400,500,700|Poppins:600");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;1,400;1,500;1,600");
</style>
<script>
//All css files
import "../assets/assets/css/base.css";
import "../assets/app-assets/css-rtl/bootstrap.css";
import "../assets/app-assets/css-rtl/bootstrap-extended.css";
import "../assets/app-assets/css-rtl/colors.css";
import "../assets/app-assets/css-rtl/themes/dark-layout.css";
import "../assets/assets/css/menu.css";
import "../assets/app-assets/css-rtl/custom-rtl.css";
import "../assets/assets/css/style-rtl.css";
export default {
name: "HomeComponent",
};
//All JS files
import "../assets/assets/js/demo.js";
import "../assets/assets/js/three.min.js";
import "../assets/assets/js/perlin.js";
import "../assets/assets/js/TweenMax.min.js";
import "../assets/assets/js/demo3.js";
import "../assets/assets/js/grid.js";
import "../assets/assets/js/imagesloaded.pkgd.min.js";
import "../assets/assets/js/anime.min.js";
import "../assets/assets/js/menu2.js";
</script>
问题出在 demo3.js 文件上。
Demo3.js
var canvas = document.querySelector("#scene");
var width = canvas.offsetWidth,
height = canvas.offsetHeight;
var renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true,
});
renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);
renderer.setSize(width, height);
renderer.setClearColor(0x161d31);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(100, width / height, 0.1, 10000);
camera.position.set(120, 0, 300);
var light = new THREE.HemisphereLight(0xffffff, 0x0c056d, 0.6);
scene.add(light);
var light = new THREE.DirectionalLight(0x590d82, 0.5);
light.position.set(100, 300, 400);
scene.add(light);
var light2 = light.clone();
light2.position.set(-100, 300, 400);
scene.add(light2);
var geometry = new THREE.IcosahedronGeometry(120, 4);
for (var i = 0; i < geometry.vertices.length; i++) {
var vector = geometry.vertices[i];
vector._o = vector.clone();
}
var material = new THREE.MeshPhongMaterial({
emissive: 0x23f660,
emissiveIntensity: 0.4,
shininess: 0,
});
var shape = new THREE.Mesh(geometry, material);
scene.add(shape);
function updateVertices(a) {
for (var i = 0; i < geometry.vertices.length; i++) {
var vector = geometry.vertices[i];
vector.copy(vector._o);
var perlin = noise.simplex3(
vector.x * 0.006 + a * 0.0002,
vector.y * 0.006 + a * 0.0003,
vector.z * 0.006
);
var ratio = perlin * 0.4 * (mouse.y + 0.3) + 0.9;
vector.multiplyScalar(ratio);
}
geometry.verticesNeedUpdate = true;
}
function render(a) {
requestAnimationFrame(render);
updateVertices(a);
renderer.render(scene, camera);
}
function onResize() {
canvas.style.width = "";
canvas.style.height = "";
width = canvas.offsetWidth;
height = canvas.offsetHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
var mouse = new THREE.Vector2(0.8, 0.5);
function onMouseMove(e) {
TweenMax.to(mouse, 0.8, {
y: e.clientY / height,
x: e.clientX / width,
ease: Power1.easeOut,
});
}
requestAnimationFrame(render);
window.addEventList ener("mousemove", onMouseMove);
var resizeTm;
window.addEventList ener("resize", function () {
resizeTm = clearTimeout(resizeTm);
resizeTm = setTimeout(onResize, 200);
});
所以,我的应用程序根本无法加载。现在我不知道如何解决这个问题。这是我第一次将 html 模板转换为 vuejs。我不知道会发生什么。 文件结构截图 (https://i.stack.imgur.com/dKzTb.png)
console.log 中错误详细信息的屏幕截图 (https://i.stack.imgur.com/9Rzap.png)
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
您将在应用呈现 DOM 之前导入
demo3.js文件(并执行它)。因此元素#scene尚不存在,导致为null。几种解决方案:
mounted挂钩后动态导入demo3.js文件:mounted() { import('../assets/assets/js/demo3.js') // dynamic import }demo3.js代码包装在函数内并将其导出。// demo3.js export function renderScene() { var canvas = document.querySelector("#scene"); var width = canvas.offsetWidth, height = canvas.offsetHeight; // [...] }import { renderScene } from '../assets/assets/js/demo3.js' export default { mounted() { renderScene() } }demo3.js代码移至 vue 组件,并使用模板引用。mounted() { const scene = this.$refs.scene if (scene) { const width = canvas.offsetWidth, height = canvas.offsetHeight; const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, }); // [...] } }