数据响应式

Vue的数据响应式

数据响应式,顾名思义,Vue会在数据改变时做出响应,更新页面、执行函数等等,这便是Vue的数据响应式。

Vue通过监听observe和代理proxy实现数据响应式。

代理proxy

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
// 需求:n 不能小于 0
// 即 data1.n = -1 应该无效,但 data1.n = 1 有效

let data1 = proxy({ data:{n:0} }) // 括号里是匿名对象,无法访问

function proxy({data}){
const obj = {}
Object.defineProperty(obj, 'n', {
get(){
return data.n
},
set(value){
if(value<0)return //加上限制条件
data.n = value
}
})
return obj // obj 就是代理
}

// data1 就是 obj
console.log(`data1:${data1.n}`) //需求三:0
data1.n = -1
console.log(`data1:${data1.n},设置为 -1 失败`) //需求三:0,设置为 -1 失败
data1.n = 1
console.log(`data1:${data1.n},设置为 1 成功`) //需求三:1,设置为 1 成功

通过代理obj来操作数据,可以给数据加上一定的限制条件。

代理不会改变原有对象。(房东找个中介,中介并不会动房子里的东西)

监听observe

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
29
30
31
32
33
34
35
36
37
38
39
// 需求:n 不能小于 0
// 同时 myData.n = -1 无效,但 myData.n = 1 有效

let myData = {n:0}
let data2 = proxy2({ data:myData }) // 括号里是匿名对象,无法访问

function proxy2({data}){
let value = data.n
Object.defineProperty(data, 'n', {
get(){
return value
},
set(newValue){
if(newValue<0)return
value = newValue
}
})
// 就加了上面几句,这几句话会监听 data

const obj = {}
Object.defineProperty(obj, 'n', {
get(){
return data.n
},
set(value){
if(value<0)return
data.n = value
}
})

return obj // obj 就是代理
}

// data2 就是 obj
console.log(`n:${data2.n}`) //n:0
myData.n = -1
console.log(`n:${data2.n},设置为 -1 失败了`) //n:0,设置为 -1 失败了
myData.n = 1
console.log(`n:${data2.n},设置为 1 成功了`) //n:1,设置为 1 成功了

通过监听,使得直接操作对象的n也能被察觉

监听会改变原有对象。(房东的房子会被中介装摄像头、窃听器,改变了房屋)

监听先将原对象的n保存了下来,然后用getter&setter替换了n的值。

Vue.set & this.$set

若对象新增了key,那么Vue可以通过Vue.set和this.$set为新key创建代理和监听

1
2
3
4
5
6
7
8
Vue.set(vm.someObject, 'b', 2)
//还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
this.$set(this.someObject,'b',2)


// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

对于数组

Vue使用了变更方法Mutation Methods

Vue 将被监听的数组的部分方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()

  • pop()

  • shift()

  • unshift()

  • splice()

  • sort()

  • reverse()

可以看到,进入Vue的数组的__proto__被Vue用变更方法替代了,原来关于Array的__proto__被放到了数组的原型的原型中。


数据响应式
https://bald3r.wang/2022/07/02/20-Vue的数据响应式/
作者
Allen
发布于
2022年7月2日
许可协议