我们在使用Vue开发的过程中,很多次都利用了Vue的数据相应式原理,如下面的这段代码
const Vue=window.Vue
const mdata={
n:1
}
new Vue({
data:mdata
,
template:`
<div>{{n}}</div>
`,
methods:{
},
}).$mount('#app')
setTimeout(()=>{
mdata.n=2
},3000)
页面中的n 2秒后会改变为2,
它的原理是什么?
原因是mdata使用了代理(proxy),它的代理就是Vue是实例对象
下面用代码演示
proxy({data}){
//这里其实应该遍历data是所有属性
let value=data.n
//下面重新定义n属性,等价于把n在原来data给删除了,然后给data重新定义了n的属性,
但是这个新的n,具有监听功能,defineProperty自带的功能
Object.defineProperty(data,'n',{
get(){
return value
}
set(newValue){
value=newValue
}
})
const obj={}
Object.defineProperty(obj,'n',{
get(){
return data.n
}
set(value){
data.n=value
}
})
return obj;
}
在外面调用
const mdata={
n:1
}
const vm=proxy(mdata)
当用户使用
mdata.n=2
的时候 就会触发set函数
vm就是代理
这个vm.n就会通过get函数得知mdata.n的变化
vm.n变化了有什么用?可以做其他的操作呀? 比如异步的render()一下呀,这样视图不就更新了吗?
const vm=proxy(mdata)
const vm =new Vue({
n:1
})
是不是有点像?
其实原理也是一样的,关键就是使用了代理这一设计模式,利用了definePropery
新人要避的两个个坑
const Vue=window.Vue
new Vue({
data:{
array:[1,2,3,4]
}
,
template:`
<div>{{array}}
<button @click="appendDate">加一个数</button>
</div>
`,
methods:{
appendDate(){
this.array[4]=6
}
},
}).$mount('#app')
这样array是不会更新的,因为没有给array的'4'添加代理和监听 如果要添加,要使用数组的变异方法 有
push pop shift unshift sort reverse splice
this.array.push(6)
就可以做到了
2.Vue.set vm.$set
vm.$set作用于数组的时候,并不会给新key添加监听