vue监听数组变化

 1 // 触发更新视图
 2 function updateView() {
 3     console.log('视图更新')
 4 }
 5 
 6 // 重新定义数组原型
 7 const oldArrayProperty = Array.prototype
 8 // 创建新对象,原型指向 oldArrayProperty ,再扩展新的方法不会影响原型
 9 const arrProto = Object.create(oldArrayProperty);
10 ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
11     arrProto[methodName] = function () {
12         updateView() // 触发视图更新
13         oldArrayProperty[methodName].call(this, ...arguments)
14         // Array.prototype.push.call(this, ...arguments)
15     }
16 })
17 
18 // 重新定义属性,监听起来
19 function defineReactive(target, key, value) {
20     // 深度监听
21     observer(value)
22 
23     // 核心 API
24     Object.defineProperty(target, key, {
25         get() {
26             return value
27         },
28         set(newValue) {
29             if (newValue !== value) {
30                 // 深度监听
31                 observer(newValue)
32 
33                 // 设置新值
34                 // 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
35                 value = newValue
36 
37                 // 触发更新视图
38                 updateView()
39             }
40         }
41     })
42 }
43 
44 // 监听对象属性
45 function observer(target) {
46     if (typeof target !== 'object' || target === null) {
47         // 不是对象或数组
48         return target
49     }
50 
51     // 污染全局的 Array 原型
52     // Array.prototype.push = function () {
53     //     updateView()
54     //     ...
55     // }
56 
57     if (Array.isArray(target)) {
58         target.__proto__ = arrProto
59     }
60 
61     // 重新定义各个属性(for in 也可以遍历数组)
62     for (let key in target) {
63         defineReactive(target, key, target[key])
64     }
65 }
66 
67 // 准备数据
68 const data = {
69     name: 'zhangsan',
70     age: 20,
71     info: {
72         address: '北京' // 需要深度监听
73     },
74     nums: [10, 20, 30]
75 }
76 
77 // 监听数据
78 observer(data)
79 
80 // 测试
81 // data.name = 'lisi'
82 // data.age = 21
83 // // console.log('age', data.age)
84 // data.x = '100' // 新增属性,监听不到 —— 所以有 Vue.set
85 // delete data.name // 删除属性,监听不到 —— 所有已 Vue.delete
86 // data.info.address = '上海' // 深度监听
87 data.nums.push(4) // 监听数组
原文地址:https://www.cnblogs.com/guwufeiyang/p/13944950.html