Heim > Fragen und Antworten > Hauptteil
Also habe ich meine benutzerdefinierte HTML-Vorlage in ein VueJS-Projekt umgewandelt. Ich habe alle CSS- und JS-Dateien importiert, die ich auf der Homepage verwenden möchte. CSS-Dateien werden problemlos geladen. Für JS-Dateien enthält das Theme einige benutzerdefinierte JS-Skripte sowie häufig verwendete Bibliotheken wie Three.js usw. Das alles habe ich unterhalb der HomeComponent im Script-Tag importiert. Aber ich habe diesen Fehler erhalten:
"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)"
Hier ist mein App.vue-Code:
<template> <router-view /> </template> <script> export default { name: "App", components: {}, }; </script>
Hier ist mein homecomponent.vue-Code (teilweise – ein Teil des Codes ist in der Vorlage versteckt):
<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>
Das Problem liegt in der Datei 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); });
Meine App wird also überhaupt nicht geladen. Jetzt weiß ich nicht, wie ich dieses Problem lösen kann. Dies ist das erste Mal, dass ich eine HTML-Vorlage in VueJS konvertiere. Ich weiß nicht, was mich erwartet. Screenshot der Dateistruktur (https://i.stack.imgur.com/dKzTb.png)
Screenshot der Fehlerdetails in console.log (https://i.stack.imgur.com/9Rzap.png)
P粉9204852852023-12-14 09:31:33
您将在应用呈现 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, }); // [...] } }