1
kevin1 2020-04-17 00:47:48 +08:00
前排等答案。
|
2
rabbbit 2020-04-17 00:49:28 +08:00
|
3
renmu 2020-04-17 01:39:47 +08:00 via Android
因为是用 es5 的 defineproperty ()来实现的,天生有缺陷所以实现不了。
它是是在每个 object 创建的时候为每个添加了 getter 和 setter,之后对 object 直接修改,自然无法进行追踪。 数组的话是因为只有 push,slice 等几个有些的函数才能触发 setter |
4
murmur 2020-04-17 08:48:24 +08:00
没有的,检测不了你可以用$set 方法(在对象中添加数据,修改特定下标)强制触发 diff,vue 基本不依赖 react 那种不可变对象的设计
|
5
Elephant696 2020-04-17 16:18:50 +08:00
vue2 是用 Object.defineProperty 来进行数据劫持的。这个方法本身就不支持劫持数组,对对象也仅仅是对对象的属性进行劫持。所以 vue 内部重写了数组的那几个方法。对对象也是做了遍历去劫持每个属性。所以可以说是因为实现不了才导致了性能问题。
当然 vue3 就没这个问题了。期待 ing |
6
xcstream OP 懂了 vue3 可以解决这个问题
|
7
Sapp 2020-08-12 19:51:03 +08:00
如果我没理解错误的话,楼上的都说的不完全对,包括 vue 文档,这是一个很复杂也很令人费解的问题,我不清楚 vue 为什么要这么设计,事实上 Object. defineProperty 是可以做到追踪数组变化的,就算在 vue 里,vue 也实现了对数组的一部分操作,比如
data() { } |
8
Sapp 2020-08-12 19:59:28 +08:00
接楼上
比如 data() { return { list: [{name: '小明'}] } } methods: { hanlderClick() { this.list[0].name ='小刚' } } 你可以尝试一下,vue 在页面是会追踪这个变化的,翻一下 vue 源码你就知道,vue 在对于数组的处理走了一个遍历,当是对象的时候劫持一下这个对象,是其他类型则不处理,这也是我很费解的地方所在,按照 vue 作者的说法不处理数组是因为性能问题,可是又为什么要对对象进行处理呢? 既然对对象进行处理,顺带把其他类型也处理了不可以么? 另一个很费解的地方就是 vue 在文档里并没有很深入的提到这个问题,只是说了 Object.defineProperty 不能劫持数组本身,但是这并不代表就不能实现解除数组元素(事实上 vue 也确实劫持了数组里的对象元素) https://codesandbox.io/s/morning-haze-6dxke?file=/src/App.vue 我写了个例子你可以试一下,单独点变化名字,是会触发变化的,但是点变化年龄并不会触发视图更新 |