Vue中你可能认为是bug的状况原来是这样的

前言

咱们知道Vue框架剧本双向数据绑定功能,在咱们使用方便的同时,还有一些细节问题咱们并不知道,接下来一块儿探讨一些吧vue

双向数据绑定

  • js变量改变影响页面
  • 页面改变影响js变量

Vue2是如何作到数据绑定的

Object.defineProperty(obj,key,{
                set:function (newV) {
                    val = newV;
                    // 通知全部用到这个属性的DOM更新
                    dep.notifyAll();
                },
                get:function () {
                    if (Dep.currentSub) {
                         // 对这个属性,新订阅一个元素
                        dep.subscribe(); 
                    }
                    return val;
                }
            });
  • 以上须要说的就是: Vue中data函数返回的对象,会通过层层遍历,最后将全部的对象经过以上方法,把其属性进行监视。
    • 经过xxx.xxx = 'xxx' 就会触发set函数
    • 经过xxx.xxx 就会触发get函数

关于数组与基本数据类型的奇葩现象

咱们声明好数组,其中放置基本数据类型react

let vm = new Vue({
        el:'#app',
        template:`
        <div>
          <p v-for="n in arr" >
            {{n}}
          </p>
        </div>`,
        data(){
          return {
            arr:[1,2,3]
          }
        }
    });

如今咱们改变其中的元素值数组

file

  • 如图所见,咱们改变数组中某个元素的值,并未发现页面改变
    file

解答疑问

  • 首先咱们知道做为data的属性,Vue都会经过for in 来遍历该对象的全部属性及子属性,而后针对每一个属性进行reactive式的数据劫持。
  • 可是当遍历数组或对象属性时,若是是非对象数据类型,就以下图
  • file
  • 咱们能够看到在Vue中 对于reactive操做,非对象数据类型是无论的,所以,咱们更改vm.arr[0] = 98没有效果

想办法解决

据说有个函数可让Vue知道你在添加属性,并完成响应式。Vue.set(obj.key.value);app

哇,有效果!!框架

咱们再来改变他看看是否能双向数据绑定函数

file

哦! No!看看源码code

file
看到了吗? 基本(原始)数据类型还给个警告!!对象

file
往下执行,若是是数组直接结束了,并不作reactive操做哦blog

总结

以前讲解了Vue作数据劫持是基于Object.defineProperty的,可是他只能作set和get,而没法监视到属性的增长或者减小,这点却是能够用Vue.set(obj.key.value)解决!而数组+基本数据类型不行! 固然话说回来,真实业务中,直接用数组操做基本数据类型的场景还真很少!
图片图片