Vue初识四

86 阅读1分钟

一、什么是响应式

看下面代码,如果修改了vm.n,那么界面中的n就会发生改变来做出响应

const vm=new Vue({data:{n:0}})

二、vue中data的bug

代码一

new Vue({
    data:{},
    template:`
        <div>{{n}}</div>
    `
}).$mount("#app")

此时页面不会显示内容,同时报错:n没有定义但是引用了

代码二

new Vue({
    data:{
        obj:{
            a:0//obj.a会被Vue监听并且代理
        }
    },
    template:`
        <div>
            {{obj.b}}
            <button @click="setB">set b</button>
        </div>
    `,
    methods:{
        setB(){
            this.obj.b=1;//页面会显示1吗
        }
    }
}).$mount("#app")

此时页面不会显示1,因为obj.b从一开始就不存在

解决方法Vue.set

new Vue({
    data:{
        obj:{
            a:0//obj.a会被Vue监听并且代理
        }
    },
    template:`
        <div>
            {{obj.b}}
            <button @click="setB">set b</button>
        </div>
    `,
    methods:{
        setB(){
            Vue.set(this.obj,'b',1);
        }
    }
}).$mount("#app")

作用是

  • 新增加一个key
  • 自动创建代理和监听
  • 触发UI更新,但不会立即更新 //这是vue的自动作用

如果data中有数组怎么办

看以下代码

new Vue({
    data:{
        array:["a","b","c"]
    },
    template:`
        <div>
            {{array}}
            <button @click="setD>set d</button>
         </div>
         `,
         methods:{
             steD(){
                 this.array[3]="d";//这样页面仍然不会显示d
                                   //数组中array:[0:"a",1:"b",2:"c",length],添加之后检测不到
                 this.$set(this.array,3,"d");//这样就可以显示d,但是实际上没办法提前先将数据写好
              }
          }
     }).$mount("#app");

在上面的代码中,若data是数组,使用传统方法无法获得d;使用Vue.set则可以,但是实际上我们无法获取提前数组的长度

new Vue({
    data:{
        array:["a","b","c"]
        },
        template:`
            <div>
                {{array}}
                <button @click="setD">set d</button>
             </div>
         `,
         methods:{
             setD(){
                 this.array.push("d");
                 console.log(this.array)
             }
         }
    }).$mount('#app')

这时,打开控制台看array的方法时,发现数组的方法新增了一层。 看以下代码

class VueArray extends Array{
    push(..args){
        const oldlength=this.length//this当前数组
        super.push(...args)
        for(let i=oldLength;i<this.length;i++){
            Vue.set(this,i,this.[i])
        }
     }
}

总结

对象在新增的key

  • Vue没有办法事先监听和代理,需要通过set来新增key,创建监听和代理,更新UI
  • 最好提前把属性都补充好,不用新增key值
  • 但若为数组,通常无法直接补充好值

数组新增key

  • 同样可以用set新增key,且创建监听和代理,更新UI
  • 不过尤雨溪篡改了数组7个API方便对数组进行增删
  • 新API会自动处理监听和代理,更新UI