options.data(Vue文档:深入响应式原理)
getter 和 setter
let obj1 = {
姓: '陈',
名: '子川',
get 姓名(){
retrun this.姓 + this.名;
},
age: 18
}
console.log("姓名:" + obj1.姓名())
let obj2 = {
姓: '陈'
名: '子川'
get 姓名(){
retrun this.姓 + this.名;
},
age: 18
}
console.log("姓名:" + obj2.姓名)
let obj3 = {
姓: '陈'
名: '子川'
get 姓名(){
retrun this.姓 + this.名;
},
set 姓名(name){
this.姓 = name[0]
this.名 = name.substring[1]
},
age: 18
}
obj3.姓名("陈圆圆")
console.log("姓 ${obj3.姓}, 名 ${obj3.名}}")
Object.defineProperty
声明完成实例后还想加入函数
let data2 = {}
data2._n = 0
Object.defineProperty(data2, 'n', {
get(){
return this._n
},
set(value){
if(value < 0) return
this._n = value
}
})
使用代理
let data3 = proxy({data: {n:0}})
function proxy({data} ){
const obj{}
Object.defineProperty(obj, 'n', {
get(){
return data.n
},
set(value){
if(value)return
data.n = value
}
})
return obj
}
使用监听拦截
let myData4 = {n:0}
let data4 = proxy2({data:myData4})
function proxy2({data}){
let value = data.n
Object.defineProperty(data, 'n', {
get(){
return value
},
set(newValue){
if(newValue<0)return
value = newValue
}
})
const obj = {}
Object.defineProperty(obj, 'n', {
get(){
return data.n
},
set(value){
if(value<0)return
data.n = value
}
})
return obj
}
小结
Object.defineProperty
- 可以给对象添加属性 value
- 可以给对象添加 getter / setter
- getter / setter 用于对属性的读写进行监控
啥是代理(设计模式)
- 对 myData 对象的属性读写, 全权由另一个对象 vm 负责
- n那么 vm 就是 myData 的代理(类似于房东)
- 比如 myData.n 不用, 偏要用 vm.n 来操作 myData.n
vm = new Vue({data: myData})
- 一. 会让 vm 成为 myData 的代理(proxy)
- 二. 会对 myData 的所有属性进行监控
- 为什么要监控, 为了防止 myData 的属性变了, vm 不知道
- vm 知道了又如何? 知道属性变了就可以调用 render(data)
- UI = render(data)
Vue data 有 BUG
Object.defineProperty 的问题
- Object.defineProperty(obj, 'n', {...})
- 必须要有一个 'n', 才能监听 & 代理 obj.n
- 如果没有给 n 怎么办
解决办法
- 方法一: 把 key 都声明好, 后面不再加属性
- 方法二: 使用 Vue.set 或者 this.$set
Vue.config.productionTip = false;
new Vue({
data: {
obj: {
a: 0,
}
},
template: `
<div>
{{obj.b}}
<button @click="setB">set b</button>
</div>
`,
methods: {
setB() {
Vue.set(this.obj, 'b', 1)
this.$set(this.obj, 'b', 1)
}
}
})
Vue.set 和 this.$set
作用
- 新增 key
- 自动创建代理和监听(如果没有创建过)
- 触发 UI 更新(但并不会理科更新)
举例
- this.$set(this.object, 'm', 100)
对象中新增的 key
- Vue 没有办法事先监听和代理
- 要使用 set 来新增 key, 创建监听和代理, 更新 UI
- 最好提前把属性都写出来, 不要新增 key
- 但是数组做不到
不新增 key
数组中新增的 key
- 也可用 set 来新增 key, 更新 UI
- 不过 Vue 篡改了7个 API 方便对数组进行增删
- 这7个API会自动处理监听和代理, 并更新 UI