Object.defineProperty的问题
Object.defineProperty(obj,'n',{...})
必须要有一个’n’,才能监听和代理obj.on对吧
如果前端开发这比较水,没有给n怎么办?
Vue会给出一个警告
Vue只会检查第一层属性。就是说
例子:
new Vue({
data(){
return:{
obj:{
a:0
}
}
},
template:`
<div>
{{obj.b}}
<button @click="setB">set B</button>
</div>
`,
methods:{
setB(){
this.obj.b = 1 //页面会显示1吗?
}
}
})
答案是不会,Vue只监听了a,一开始不存在的b无法被监听,这就是bug。
解决办法
一、把key都声明好,后面不用再加属性了
二、使用Vue.set或者this.$set
methods:{
setB(){
Vue.set(this.obj,'b',1) //这是写法一
this.$set(this.obj,'b',1)//这是写法二
}
}
Vue.set和this.$set
作用:
- 新增key
- 自动创建代理和监听(如果没有创建过)
- 触发UI更新(但不会立即更新)
如果data里有数组,而数组无法提前全部声明好的情况怎么办?
new Vue({
data(){
array:["a","b","c"]
},
template:`
<div>
{{array}}
<button @@click="setD">set b</button>
</div>
`,
methods:{
setD(){
this.array[3] = "d" //页面中会显示"d"吗?等下,你为什么不用this.array.push("d")
}
}
}).$mount("#app")
array:[“a”,”b”,”c”]可以理解为
array:[0:”a”,1:”b”,2:”c”]
所以第4个位置是不存在的
解决方法:变异方法
methods:{
setD(){
this.array.push("d") //这个方法是被改过的,不是以前的push,所以也可以改
}
}
Vue在array对象传给它之后,Vue会篡改数组API,在中间加一层原型,提供7个方法。
资料来源:饥人谷