vue中使用three.js报错怎么办

发布时间:2022-03-05 14:01:30 作者:小新
来源:亿速云 阅读:404

小编给大家分享一下vue中使用three.js报错怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

前言

最近在学习three.js,同时也学习一下vue3,然后就出现问题了,报错直接用不了,错误信息如下:

vue中使用three.js报错怎么办

Uncaught TypeError: 'get' on proxy: property 'modelViewMatrix' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#' but got '[object Object]')

这个是什么鬼???相信大家都把错误信息复制到百度搜了一下解决方案吧?遇到问题的人并不多,解决方案就是把scene、mesh 啥的放到全局变量中,不放到data中,好的问题解决了。

我这样写是不是有点水文的嫌疑?作为一个成熟的程序员怎么能水文呢?我得找到为什么会出现这个问题才行,于是我花了两个小时找到问题所在,也是怪自己不够专业,不然应该花不了两个小时。

1. vue的问题?

众所周知,vue3是通过Proxy实现的数据双向绑定,vue2是通过defindeProperty实现的数据双向绑定,vue2的源码我也看过,应该也是会有这个问题的,因为在开发模式下面,如果浏览器支持Proxy还是会用Proxy,我没有用vue2去尝试,大家可以自行去尝试,不出意外也会有这个问题。
上面说了一堆,就是为了引出Proxy的异常情况,好了又可以学习一下Proxy的知识了

2. Proxy的异常情况

在使用Proxy时,当属性存在属性特性configurable: false, value: undefined,时,则取其属性值时会报错:

const handle = {
  get() {
    return 1;
  },
};

const obj = Object.create(null);
Object.defineProperty(obj, 'a', {
  configurable: false,
});
Object.defineProperty(obj, 'b', {
  value: undefined,
});
Object.defineProperty(obj, 'c', {
  configurable: true,
  value: 'c',
});

const proxy = new Proxy(obj, handle);
console.log(proxy.a); // 报错TypeError: 'get' on proxy: property 'a' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected 'undefined' but got '1')
console.log(proxy.b); // 报错Uncaught TypeError: 'get' on proxy: property 'b' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected 'undefined' but got '1')
console.log(proxy.c); // 1

看看上面的报错,是不是很熟悉?这样看是不是一下就知道是什么问题了?

3. Three.js 的问题

this.scene = new Scene();
this.scene.modelViewMatrix;

直接运行上面的代码,就会看到文首出现的错误,错误原因就是因为configurable设置为false,找到问题就要解决问题,是不是觉得直接使用defineProperty就可以解决了?
很抱歉,这个不行,再来学习一下defineProperty。

4. defineProperty异常情况

MDN中是这样描述的

如果属性已经存在,Object.defineProperty()将尝试根据描述符中的值以及对象当前的配置来修改这个属性。如果旧描述符将其configurable 属性设置为false,则该属性被认为是“不可配置的”,并且没有属性可以被改变(除了单向改变 writable 为 false)。当属性不可配置时,不能在数据和访问器属性类型之间切换。
当试图改变不可配置属性(除了 value 和 writable 属性之外)的值时,会抛出TypeError,除非当前值和新值相同。

也就是说之前定义了configurable为false,就不能再将configurable改为true了,那怎么办?我说了问题当然是要给你解决的。

5. 解决

之前在网上查了,全局变量来处理,但是我使用的vue啊,我当然是希望将它定义到data中的,但是定义到data中就会自动生成代理,那就只能从源码入手了。 我也就不讲我是怎么去找源码的,我直接上解决之后的吧,在node_modules\three\build\three.module.js这个文件中,第7392行,里面的代码如下:

Object.defineProperties( this, {
 position: {
  configurable: true,
  enumerable: true,
  value: position
 },
 rotation: {
  configurable: true,
  enumerable: true,
  value: rotation
 },
 quaternion: {
  configurable: true,
  enumerable: true,
  value: quaternion
 },
 scale: {
  configurable: true,
  enumerable: true,
  value: scale
 },
 modelViewMatrix: {
  value: new Matrix4()
 },
 normalMatrix: {
  value: new Matrix3()
 }
} );

看到了吧,里面有一个modelViewMatrix属性,它没有设置configurable属性描述,也就是默认为false,加上就好了,改好了如下:

Object.defineProperties( this, {
 position: {
  configurable: true,
  enumerable: true,
  value: position
 },
 rotation: {
  configurable: true,
  enumerable: true,
  value: rotation
 },
 quaternion: {
  configurable: true,
  enumerable: true,
  value: quaternion
 },
 scale: {
  configurable: true,
  enumerable: true,
  value: scale
 },
 modelViewMatrix: {
  configurable: true,
  value: new Matrix4()
 },
 normalMatrix: {
  value: new Matrix3()
 }
} );

然后重启服务,就不会报错了,当然这种方式是有缺陷的,因为改了只是你本地的,你其他同事的代码并没有改,如果要升级three.js也会把改了的代码重新覆盖,同时也不知道为什么three.js要这样处理这个变量,这个就看自己是怎么处理的,我这次只处理这个问题。

以上是“vue中使用three.js报错怎么办”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

推荐阅读:
  1. 使用Three.js的材质
  2. vue 在使用vue-router报错 Cannot read property matched

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue three.js

上一篇:Rust模块怎么用

下一篇:Entity Framework如何使用LINQ操作实体

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》