Object.defineProperty的问题

  1. Object.defineProperty(obj,'n',{...})

必须要有一个’n’,才能监听和代理obj.on对吧
如果前端开发这比较水,没有给n怎么办?
Vue会给出一个警告
Vue只会检查第一层属性。就是说

例子:

  1. new Vue({
  2. data(){
  3. return:{
  4. obj:{
  5. a:0
  6. }
  7. }
  8. },
  9. template:`
  10. <div>
  11. {{obj.b}}
  12. <button @click="setB">set B</button>
  13. </div>
  14. `,
  15. methods:{
  16. setB(){
  17. this.obj.b = 1 //页面会显示1吗?
  18. }
  19. }
  20. })

答案是不会,Vue只监听了a,一开始不存在的b无法被监听,这就是bug。

解决办法

一、把key都声明好,后面不用再加属性了

二、使用Vue.set或者this.$set

  1. methods:{
  2. setB(){
  3. Vue.set(this.obj,'b',1) //这是写法一
  4. this.$set(this.obj,'b',1)//这是写法二
  5. }
  6. }

Vue.set和this.$set

作用:

  1. 新增key
  2. 自动创建代理和监听(如果没有创建过)
  3. 触发UI更新(但不会立即更新)

如果data里有数组,而数组无法提前全部声明好的情况怎么办?

  1. new Vue({
  2. data(){
  3. array:["a","b","c"]
  4. },
  5. template:`
  6. <div>
  7. {{array}}
  8. <button @@click="setD">set b</button>
  9. </div>
  10. `,
  11. methods:{
  12. setD(){
  13. this.array[3] = "d" //页面中会显示"d"吗?等下,你为什么不用this.array.push("d")
  14. }
  15. }
  16. }).$mount("#app")

array:[“a”,”b”,”c”]可以理解为
array:[0:”a”,1:”b”,2:”c”]
所以第4个位置是不存在的

解决方法:变异方法

  1. methods:{
  2. setD(){
  3. this.array.push("d") //这个方法是被改过的,不是以前的push,所以也可以改
  4. }
  5. }

Vue在array对象传给它之后,Vue会篡改数组API,在中间加一层原型,提供7个方法。

资料来源:饥人谷