所以我將自訂 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)
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, }); // [...] } }