通过数组下标或者长度无法触发更新
# 无法触发更新的原因
通过数组下标改变数组元素或者改变数组的length都是无法触发视图更新的。
原因是由于vue2 采用的是 Object.definePrototype
来实现响应式,未对数组的每一项索引和长度进行监听,消耗太大。
vue监听数组的源码:
observeArray (items: Array<any>) {
for (let i = 0, l = items.length; i < l; i++) {
observe(items[i])
}
}
export function observe (value: any, asRootData: ?boolean): Observer | void {
//不是object类型跳出函数
if (!isObject(value) || value instanceof VNode) {
return
}
let ob: Observer | void
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__
} else if (
shouldObserve &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
ob = new Observer(value)
}
if (asRootData && ob) {
ob.vmCount++
}
return ob
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
通过上面代码可以看出,vue中只对数组中的每个元素进行了监听,而没有对数组的每个索引进行监听。
# 主动触发更新有两种方式:
Vue.set
Array.prototype.splice
# 那为什么使用数组的push、splice、shift等方法触发页面的改变
Vue对数组的这些方法进行了重写(函数劫持
)