Three.js在vue中的使用(一)-基础

Three.js 是一个基于 WebGL 的 JavaScript 3D 图形库,它简化了在网页中创建和渲染 3D 场景的复杂性。Three.js 提供了丰富的功能,如光照、材质、几何体、动画、控制器等,使得开发者可以快速构建交互式的 3D 应用。


🧠 Three.js 原理概述

1. WebGL 基础

  • Three.js 底层使用 WebGL(Web Graphics Library)进行图形渲染。
  • WebGL 是一种低级 API,允许直接操作 GPU 进行高性能图形绘制。
  • Three.js 对 WebGL 进行封装,屏蔽了底层复杂性。

2. 核心组件

Three.js 的基本结构通常包括以下几个核心对象:

组件 作用
Scene 场景,是所有 3D 对象的容器
Camera 摄像机,决定从哪个角度观察场景(常用 PerspectiveCamera
Renderer 渲染器,负责将场景和摄像机的内容渲染到 HTML 页面中的 canvas 元素
Mesh 网格对象,由几何体(Geometry)和材质(Material)组成
Li
chunk-vendors.js:13463 [HMR] Waiting for update signal from WDS... main.js:26 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952 addEventListener @ event.js:201 mountSingleDOMEventListener @ HandlerProxy.js:412 eval @ HandlerProxy.js:359 each @ util.js:300 mountLocalDOMEventListeners @ HandlerProxy.js:358 HandlerDomProxy @ HandlerProxy.js:486 ZRender @ zrender.js:138 init @ zrender.js:49 ECharts @ echarts.js:206 init @ echarts.js:1928 mounted @ cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/components/areaChart.vue?vue&type=script&lang=js:199 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 insert @ vue.runtime.esm.js:4480 invokeInsertHook @ vue.runtime.esm.js:6999 patch @ vue.runtime.esm.js:7213 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Vue.$forceUpdate @ vue.runtime.esm.js:3849 forceRender_1 @ vue.runtime.esm.js:2816 eval @ vue.runtime.esm.js:2836 eval @ vue.runtime.esm.js:370 Promise.then resolveAsyncComponent @ vue.runtime.esm.js:2856 createComponent @ vue.runtime.esm.js:4531 _createElement @ vue.runtime.esm.js:2971 createElement$1 @ vue.runtime.esm.js:2921 vm._c @ vue.runtime.esm.js:2694 render @ cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"3bd8c2c6-vue-loader-template"}!./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/mainPage.vue?vue&type=template&id=0be33bfc&scoped=true:28 Vue._render @ vue.runtime.esm.js:2739 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher @ vue.runtime.esm.js:3491 mountComponent @ vue.runtime.esm.js:3947 Vue.$mount @ vue.runtime.esm.js:8830 init @ vue.runtime.esm.js:4464 merged @ vue.runtime.esm.js:4618 createComponent @ vue.runtime.esm.js:6624 createElm @ vue.runtime.esm.js:6578 updateChildren @ vue.runtime.esm.js:6873 patchVnode @ vue.runtime.esm.js:6966 updateChildren @ vue.runtime.esm.js:6840 patchVnode @ vue.runtime.esm.js:6966 patch @ vue.runtime.esm.js:7134 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Dep.notify @ vue.runtime.esm.js:790 reactiveSetter @ vue.runtime.esm.js:1021 eval @ vue-router.esm.js:3013 eval @ vue-router.esm.js:3012 updateRoute @ vue-router.esm.js:2422 eval @ vue-router.esm.js:2271 eval @ vue-router.esm.js:2410 step @ vue-router.esm.js:2092 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 eval @ vue-router.esm.js:2405 step @ vue-router.esm.js:2092 eval @ vue-router.esm.js:2096 eval @ vue-router.esm.js:2392 eval @ vue-router.esm.js:2135 eval @ vue-router.esm.js:2211 Promise.then eval @ vue-router.esm.js:2158 eval @ vue-router.esm.js:2179 eval @ vue-router.esm.js:2179 flatMapComponents @ vue-router.esm.js:2178 eval @ vue-router.esm.js:2114 iterator @ vue-router.esm.js:2370 step @ vue-router.esm.js:2095 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 confirmTransition @ vue-router.esm.js:2400 transitionTo @ vue-router.esm.js:2268 init @ vue-router.esm.js:3004 beforeCreate @ vue-router.esm.js:1306 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 Vue._init @ vue.runtime.esm.js:5745 Vue @ vue.runtime.esm.js:5818 eval @ main.js:26 ./src/main.js @ app.js:1304 __webpack_require__ @ app.js:854 fn @ app.js:151 1 @ app.js:1377 __webpack_require__ @ app.js:854 checkDeferredModules @ app.js:46 (anonymous) @ app.js:994 (anonymous) @ app.js:997 main.js:26 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952 addEventListener @ event.js:201 mountSingleDOMEventListener @ HandlerProxy.js:412 eval @ HandlerProxy.js:359 each @ util.js:300 mountLocalDOMEventListeners @ HandlerProxy.js:358 HandlerDomProxy @ HandlerProxy.js:486 ZRender @ zrender.js:138 init @ zrender.js:49 ECharts @ echarts.js:206 init @ echarts.js:1928 mounted @ cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/components/page2/barChart.vue?vue&type=script&lang=js:189 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 insert @ vue.runtime.esm.js:4480 invokeInsertHook @ vue.runtime.esm.js:6999 patch @ vue.runtime.esm.js:7213 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Vue.$forceUpdate @ vue.runtime.esm.js:3849 forceRender_1 @ vue.runtime.esm.js:2816 eval @ vue.runtime.esm.js:2836 eval @ vue.runtime.esm.js:370 Promise.then resolveAsyncComponent @ vue.runtime.esm.js:2856 createComponent @ vue.runtime.esm.js:4531 _createElement @ vue.runtime.esm.js:2971 createElement$1 @ vue.runtime.esm.js:2921 vm._c @ vue.runtime.esm.js:2694 render @ cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"3bd8c2c6-vue-loader-template"}!./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/mainPage.vue?vue&type=template&id=0be33bfc&scoped=true:48 Vue._render @ vue.runtime.esm.js:2739 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher @ vue.runtime.esm.js:3491 mountComponent @ vue.runtime.esm.js:3947 Vue.$mount @ vue.runtime.esm.js:8830 init @ vue.runtime.esm.js:4464 merged @ vue.runtime.esm.js:4618 createComponent @ vue.runtime.esm.js:6624 createElm @ vue.runtime.esm.js:6578 updateChildren @ vue.runtime.esm.js:6873 patchVnode @ vue.runtime.esm.js:6966 updateChildren @ vue.runtime.esm.js:6840 patchVnode @ vue.runtime.esm.js:6966 patch @ vue.runtime.esm.js:7134 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Dep.notify @ vue.runtime.esm.js:790 reactiveSetter @ vue.runtime.esm.js:1021 eval @ vue-router.esm.js:3013 eval @ vue-router.esm.js:3012 updateRoute @ vue-router.esm.js:2422 eval @ vue-router.esm.js:2271 eval @ vue-router.esm.js:2410 step @ vue-router.esm.js:2092 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 eval @ vue-router.esm.js:2405 step @ vue-router.esm.js:2092 eval @ vue-router.esm.js:2096 eval @ vue-router.esm.js:2392 eval @ vue-router.esm.js:2135 eval @ vue-router.esm.js:2211 Promise.then eval @ vue-router.esm.js:2158 eval @ vue-router.esm.js:2179 eval @ vue-router.esm.js:2179 flatMapComponents @ vue-router.esm.js:2178 eval @ vue-router.esm.js:2114 iterator @ vue-router.esm.js:2370 step @ vue-router.esm.js:2095 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 confirmTransition @ vue-router.esm.js:2400 transitionTo @ vue-router.esm.js:2268 init @ vue-router.esm.js:3004 beforeCreate @ vue-router.esm.js:1306 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 Vue._init @ vue.runtime.esm.js:5745 Vue @ vue.runtime.esm.js:5818 eval @ main.js:26 ./src/main.js @ app.js:1304 __webpack_require__ @ app.js:854 fn @ app.js:151 1 @ app.js:1377 __webpack_require__ @ app.js:854 checkDeferredModules @ app.js:46 (anonymous) @ app.js:994 (anonymous) @ app.js:997 main.js:26 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952 addEventListener @ event.js:201 mountSingleDOMEventListener @ HandlerProxy.js:412 eval @ HandlerProxy.js:359 each @ util.js:300 mountLocalDOMEventListeners @ HandlerProxy.js:358 HandlerDomProxy @ HandlerProxy.js:486 ZRender @ zrender.js:138 init @ zrender.js:49 ECharts @ echarts.js:206 init @ echarts.js:1928 mounted @ cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/components/page2/pieChart03.vue?vue&type=script&lang=js:21 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 insert @ vue.runtime.esm.js:4480 invokeInsertHook @ vue.runtime.esm.js:6999 patch @ vue.runtime.esm.js:7213 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Vue.$forceUpdate @ vue.runtime.esm.js:3849 forceRender_1 @ vue.runtime.esm.js:2816 eval @ vue.runtime.esm.js:2836 eval @ vue.runtime.esm.js:370 Promise.then resolveAsyncComponent @ vue.runtime.esm.js:2856 createComponent @ vue.runtime.esm.js:4531 _createElement @ vue.runtime.esm.js:2971 createElement$1 @ vue.runtime.esm.js:2921 vm._c @ vue.runtime.esm.js:2694 render @ cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"3bd8c2c6-vue-loader-template"}!./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/mainPage.vue?vue&type=template&id=0be33bfc&scoped=true:109 Vue._render @ vue.runtime.esm.js:2739 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher @ vue.runtime.esm.js:3491 mountComponent @ vue.runtime.esm.js:3947 Vue.$mount @ vue.runtime.esm.js:8830 init @ vue.runtime.esm.js:4464 merged @ vue.runtime.esm.js:4618 createComponent @ vue.runtime.esm.js:6624 createElm @ vue.runtime.esm.js:6578 updateChildren @ vue.runtime.esm.js:6873 patchVnode @ vue.runtime.esm.js:6966 updateChildren @ vue.runtime.esm.js:6840 patchVnode @ vue.runtime.esm.js:6966 patch @ vue.runtime.esm.js:7134 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Dep.notify @ vue.runtime.esm.js:790 reactiveSetter @ vue.runtime.esm.js:1021 eval @ vue-router.esm.js:3013 eval @ vue-router.esm.js:3012 updateRoute @ vue-router.esm.js:2422 eval @ vue-router.esm.js:2271 eval @ vue-router.esm.js:2410 step @ vue-router.esm.js:2092 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 eval @ vue-router.esm.js:2405 step @ vue-router.esm.js:2092 eval @ vue-router.esm.js:2096 eval @ vue-router.esm.js:2392 eval @ vue-router.esm.js:2135 eval @ vue-router.esm.js:2211 Promise.then eval @ vue-router.esm.js:2158 eval @ vue-router.esm.js:2179 eval @ vue-router.esm.js:2179 flatMapComponents @ vue-router.esm.js:2178 eval @ vue-router.esm.js:2114 iterator @ vue-router.esm.js:2370 step @ vue-router.esm.js:2095 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 confirmTransition @ vue-router.esm.js:2400 transitionTo @ vue-router.esm.js:2268 init @ vue-router.esm.js:3004 beforeCreate @ vue-router.esm.js:1306 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 Vue._init @ vue.runtime.esm.js:5745 Vue @ vue.runtime.esm.js:5818 eval @ main.js:26 ./src/main.js @ app.js:1304 __webpack_require__ @ app.js:854 fn @ app.js:151 1 @ app.js:1377 __webpack_require__ @ app.js:854 checkDeferredModules @ app.js:46 (anonymous) @ app.js:994 (anonymous) @ app.js:997 cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/components/areaChart.vue?vue&type=script&lang=js:22 报警信息此时: {__ob__: Observer} cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/components/page2/barChart.vue?vue&type=script&lang=js:22 报警信息此时: {__ob__: Observer} main.js:26 加载 3D 模型失败: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON at JSON.parse (<anonymous>) at GLTFLoader.parse (GLTFLoader.js:387:17) at Object.eval [as onLoad] (GLTFLoader.js:249:11) at eval (three.core.js:44796:38) eval @ cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/mainPage.vue?vue&type=script&lang=js:132 _onError @ GLTFLoader.js:225 eval @ GLTFLoader.js:259 eval @ three.core.js:44796 Promise.then load @ three.core.js:44784 load @ GLTFLoader.js:245 initThreeModel @ cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/mainPage.vue?vue&type=script&lang=js:121 eval @ cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/mainPage.vue?vue&type=script&lang=js:153 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 Vue.$nextTick @ vue.runtime.esm.js:2718 mounted @ iview.js:20290 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 insert @ vue.runtime.esm.js:4480 invokeInsertHook @ vue.runtime.esm.js:6999 patch @ vue.runtime.esm.js:7213 Vue._update @ vue.runtime.esm.js:3824 updateComponent @ vue.runtime.esm.js:3930 Watcher.get @ vue.runtime.esm.js:3501 Watcher.run @ vue.runtime.esm.js:3577 flushSchedulerQueue @ vue.runtime.esm.js:4180 eval @ vue.runtime.esm.js:3198 flushCallbacks @ vue.runtime.esm.js:3120 Promise.then timerFunc @ vue.runtime.esm.js:3145 nextTick @ vue.runtime.esm.js:3210 queueWatcher @ vue.runtime.esm.js:4266 Watcher.update @ vue.runtime.esm.js:3568 Dep.notify @ vue.runtime.esm.js:790 reactiveSetter @ vue.runtime.esm.js:1021 eval @ vue-router.esm.js:3013 eval @ vue-router.esm.js:3012 updateRoute @ vue-router.esm.js:2422 eval @ vue-router.esm.js:2271 eval @ vue-router.esm.js:2410 step @ vue-router.esm.js:2092 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 eval @ vue-router.esm.js:2405 step @ vue-router.esm.js:2092 eval @ vue-router.esm.js:2096 eval @ vue-router.esm.js:2392 eval @ vue-router.esm.js:2135 eval @ vue-router.esm.js:2211 Promise.then eval @ vue-router.esm.js:2158 eval @ vue-router.esm.js:2179 eval @ vue-router.esm.js:2179 flatMapComponents @ vue-router.esm.js:2178 eval @ vue-router.esm.js:2114 iterator @ vue-router.esm.js:2370 step @ vue-router.esm.js:2095 step @ vue-router.esm.js:2099 step @ vue-router.esm.js:2099 runQueue @ vue-router.esm.js:2103 confirmTransition @ vue-router.esm.js:2400 transitionTo @ vue-router.esm.js:2268 init @ vue-router.esm.js:3004 beforeCreate @ vue-router.esm.js:1306 invokeWithErrorHandling @ vue.runtime.esm.js:3072 callHook$1 @ vue.runtime.esm.js:4087 Vue._init @ vue.runtime.esm.js:5745 Vue @ vue.runtime.esm.js:5818 eval @ main.js:26 ./src/main.js @ app.js:1304 __webpack_require__ @ app.js:854 fn @ app.js:151 1 @ app.js:1377 __webpack_require__ @ app.js:854 checkDeferredModules @ app.js:46 (anonymous) @ app.js:994 (anonymous) @ app.js:997
11-11
<think>我们面临三个问题: 1. 'HMR等待WDS更新信号'的日志输出(属于信息性日志,通常可以忽略,但用户希望关闭) 2. 添加非被动事件监听器到滚动阻塞事件(控制台警告) 3. 加载3D模型失败,错误为:SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON 下面逐解决: ### 、关闭[HMR]日志(参考之前回答和引用[1][2][3]) 问题:控制台输出`[HMR] Waiting for update signal from WDS...`,这是webpack热更新的日志,虽然不影响功能,但用户可能觉得干扰。 解决方案: 1. **修改vue.config.js配置(推荐)**:通过配置devServer.client.logging来减少日志级别。 ```javascript // vue.config.js module.exports = { devServer: { client: { logging: 'error', // 只输出错误日志 overlay: false, // 可选:关闭浏览器全屏覆盖错误 } } } ``` 这样设置后,只有错误才会在控制台显示,信息级别的HMR日志将不再显示。 2. **修改webpack的log.js(临时,不推荐)**:如之前所述,修改node_modules/webpack/hot/log.js,注释掉console.log。但这种方法在重新安装node_modules后会失效。 3. **使用webpack插件(高级)**:可以编写个webpack插件来过滤日志,但相对复杂,不推荐。 ### 二、非被动事件监听器警告(滚动阻塞事件) 问题:在控制台看到类似警告: ``` [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. ``` 原因:事件监听器阻塞了滚动,导致页面响应延迟。现代浏览器推荐将事件监听器标记为`passive`以提升滚动性能。 解决方案: 1. **在事件监听器中添加passive选项**: 例如,使用addEventListener时: ```javascript element.addEventListener('touchstart', handler, { passive: true }); ``` 但注意:如果事件处理函数中调用了`event.preventDefault()`,则不能使用passive,因为passive会忽略preventDefault。 2. **使用第三方库修复**: 如果是第三方库(如Vue的某些UI组件)引起的,可以尝试使用`default-passive-events`库。 安装: ```bash npm install default-passive-events --save ``` 在main.js中引入: ```javascript import 'default-passive-events'; ``` 3. **框架层面的修复(Vue)**: 在Vue中,我们可以通过全局配置来为特定的事件添加passive选项(Vue2.4+支持): ```javascript Vue.config.productionTip = false; Vue.config.performance = true; // 为特定事件添加passive Vue.config.optionMergeStrategies.domEvent = (parent, child, vm) => { if (!child) return parent if (!parent) return child return function mergedHandler(...args) { const [event] = args if (event.type === 'touchstart' || event.type === 'touchmove') { event.passive = true } parent.call(this, ...args) child.call(this, ...args) } } ``` 但这种方法较为复杂,且可能不适用于所有情况。更推荐使用第二种方法。 ### 三、加载3D模型失败(SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON) 问题描述:在加载3D模型(如GLB、GLTF)时,控制台报错:`Unexpected token '<'`,并且错误内容显示接收到了HTML文档(以`<!DOCTYPE html>`开头)。这通常意味着请求的模型文件路径错误,服务器返回了个HTML页面(通常是404页面)而不是模型文件。 分析:根据引用[2][3][4][5]可知,这种错误通常与资源路径不正确有关,特别是在Vue项目中使用了history路由模式时,相对路径和绝对路径的配置差异可能导致此类问题。 解决方案: 1. **检查模型文件路径**: - 确保在代码中引用的模型路径是正确的。如果是放在public目录下,则使用绝对路径: ```javascript // 正确:public目录下的文件使用绝对路径(以/开头) loader.load('/models/your-model.glb', ...) ``` - 如果是放在src/assets目录下,则使用require或import相对路径: ```javascript // 使用require loader.load(require('@/assets/models/your-model.glb'), ...) ``` 或者(如果loader支持URL对象): ```javascript import modelUrl from '@/assets/models/your-model.glb'; loader.load(modelUrl, ...) ``` 2. **配置publicPath(重要)**: 在vue.config.js中,设置正确的publicPath。根据引用[2][5],如果使用history模式,publicPath必须为绝对路径`'/'`而不能是相对路径`'./'`。 ```javascript // vue.config.js module.exports = { publicPath: '/', // 生产环境构建时使用的publicPath // ...其他配置 } ``` 3. **服务器配置**: - 确保服务器(如Nginx, Apache, IIS)正确配置了静态资源目录,并将模型文件的MIME类型设置为正确的类型(如.glb为model/gltf-binary)。 - 对于使用history模式的路由,需要配置服务器支持(因为直接访问深层路径可能会返回index.html,导致模型请求被路由拦截而返回HTML)。引用[5]提到可能需要URL重写。 以Nginx为例,配置个重写规则: ```nginx location / { try_files $uri $uri/ /index.html; } ``` 但是注意,这个规则会导致所有不存在的路径都返回index.html,因此我们需要确保模型文件的路径是真实存在的。或者,我们可以将模型文件放在不会被路由拦截的路径下(如static目录)。 4. **检查请求路径(Network面板)**: 在浏览器开发者工具的Network面板中,查看模型文件的请求: - 请求URL是否正确? - 响应状态码是200还是404/其他? - 响应内容是否为HTML(说明路径错误)? 5. **使用正确的Loader和文件类型**: 确保你使用的加载器(如GLTFLoader)支持该文件类型。同时,文件本身应该是有效的。 6. **处理跨域问题**: 如果模型文件在另个域上,确保服务器设置了CORS头。 7. **避免路由拦截**: 如果模型文件请求被路由拦截(比如在Vue Router中定义了类似`'/model/:id'`的路由),则应该调整路由,或者将模型文件放在public目录以避免被路由拦截。 总结错误原因:请求模型文件时,由于路径错误或服务器配置问题,返回了HTML页面(比如404页面),而加载器期望的是二进制或JSON格式的模型文件,解析HTML时遇到`<`符号就报错了。 ### 补充:三个问题的关联性 这三个问题都是开发中常见的,但彼此独立。可以分别按照上述方法解决。 §§相关问题§§ 1. Vue项目中如何正确配置静态资源路径(publicPath)? 2. 如何处理浏览器中非被动事件监听器的警告? 3. 服务器部署Vue应用(使用history模式)后出现资源加载错误如何解决? 4.Vue项目中如何正确引入和加载Three.js的3D模型? 5. 如何使用Nginx配置Vue项目的history模式? </think>以下是针对 Vue 项目中三个关键问题的完整解决方案: ### 、解决 HMR 等待 WDS 更新信号日志 #### 问题本质 Webpack 热更新机制的正常提示信息,可通过配置关闭: ```javascript // vue.config.js module.exports = { devServer: { client: { logging: "error", // 仅显示错误日志 overlay: false // 关闭全屏错误覆盖 } } } ``` > **效果**:控制台将只显示关键错误信息,HMR 状态提示被过滤[^1][^2] #### 替代方案(临时) ```javascript // main.js if (process.env.NODE_ENV === "development") { const originalLog = console.log; console.log = (...args) => { if (!args[0].includes("[HMR]")) originalLog(...args); }; } ``` --- ### 二、修复滚动阻塞事件警告 #### 问题原因 触发滚动的事件监听器(如 `touchstart`)未标记为被动模式: ``` [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event... ``` #### 解决方案 1. **原生事件监听修复**: ```javascript // 添加 passive 选项 element.addEventListener("touchstart", handler, { passive: true }); ``` 2. **Vue 事件指令修复**: ```html <!-- 模板中使用 --> <div @touchstart.passive="handleTouch">...</div> ``` 3. **全局修复(推荐)**: ```bash npm install default-passive-events ``` ```javascript // main.js import "default-passive-events"; ``` > **原理**:自动为滚动相关事件添加 `passive: true` 属性[^3] --- ### 三、解决 3D 模型加载失败(SyntaxError: Unexpected token '<') #### 错误本质 ```json 加载 3D 模型失败: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON ``` 表明模型加载请求返回了 HTML 文档(通常是 404 页面)而非模型文件 #### 🔍 根本原因排查(参考引用[2][3][5]) 1. **路径配置错误**: - 开发环境有效但生产环境失效 - 错误使用相对路径 `./model.glb`(应使用绝对路径 `/model.glb`) 2. **路由模式冲突**: ```javascript // router/index.js export default new Router({ mode: "history", // 导致路径解析错误 // 改为: mode: "hash", // 修复方案[^4] }) ``` 3. **服务器配置问题**: - 未配置 MIME 类型 - Nginx/Apache 未正确处理静态资源请求 #### ✅ 完整解决方案 1. **路径修正**: ```javascript // 错误 ❌ loader.load("./assets/model.glb") // 正确 ✅(public目录) loader.load("/models/model.glb") // 正确 ✅(src/assets目录) loader.load(require("@/assets/model.glb")) ``` 2. **vue.config.js 配置**: ```javascript module.exports = { publicPath: "/", // 必须为根路径[^2][^5] chainWebpack: config => { config.module .rule("glb") .test(/\.glb$/) .use("file-loader") .loader("file-loader") .options({ name: "static/models/[name].[hash:8].[ext]" }) } } ``` 3. **服务器配置示例(Nginx)**: ```nginx location / { try_files $uri $uri/ /index.html; # history模式必需 } location /static/models { add_header Access-Control-Allow-Origin *; types { model/gltf-binary glb; application/octet-stream glb; } } ``` 4. **模型加载最佳实践**: ```javascript new GLTFLoader().load( process.env.NODE_ENV === "production" ? "/static/models/scene.glb" : require("@/dev_models/scene.glb"), gltf => scene.add(gltf.scene), null, error => console.error("模型加载失败:", error) // 捕获具体错误 ); ``` --- ### 问题关联分析 | 问题类型 | 根本原因 | 解决方案 | |-----------------------|----------------------------------|----------------------------------| | HMR 日志 | Webpack 开发服务器配置 | 调整 logging 级别 | | 非被动事件监听器 | 滚动事件未标记 passive | 全局注入 passive 事件处理 | | 模型加载失败 | 路径解析错误/路由模式冲突 | 绝对路径 + hash路由 + 正确配置 | > **关键检查点**:浏览器开发者工具的 Network 选项卡查看模型请求: > 1. 状态码是否 200(非 404/304) > 2. 响应内容是否为模型二进制数据(非 HTML) > 3. Content-Type 是否为 `model/gltf-binary`
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香蕉可乐荷包蛋

努力写有用的code

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值