最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 你不知道的Vue双向数据绑定-新手篇

    正文概述 掘金(onlyShadow)   2021-08-02   578

    面试官:请你描述一下你对Vue的数据双向绑定原理的理解

    我:Vue2.0版本的数据双向绑定是基于Object.defineProperty这个API来实现的,它是底层暴露给我们的一个封装方法.参数分别是被监听的对象obj,被监听的属性a,以及第三个用来设定属性特性值的对象;我们可以利用get和set这两个回调函数来实现双向绑定

    面试官:那么这两个回调函数是否还有别的作用?Vue中的响应依赖又是什么?如何进行收集和触发?你又是怎么理解观察者和监听者的?

    我:

    你不知道的Vue双向数据绑定-新手篇

    Vue的数据渲染过程

    请看下面这段代码

    <template>
      <div id="app">
        <div>
          {{ msg }}
        </div>
        <span>{{ msg + 1 }}</span>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          msg: 123,
        };
      },
      computed:{
        getMsg(){
          return this.msg + 100;
        }
      },
      watch:{
        msg:function(val){
          console.log(val);
        }
      }
    };
    </script>
    

    那么以上代码在Vue的处理中大概走这几步:

    1. 使用Object.defineProperty对data中的msg进行数据劫持
    2. 收集msg的数据依赖,并派一个监听者(watcher),来对这些数据依赖进行挨个监听
    3. 将已经收集好的数据依赖进行保存,当数据发生变化时触发它们,对数据和Dom进行双向通知
    4. 生成虚拟DOM->真实DOM
    5. 挂载到页面上

    我们来尝试一下实现以上第1,2,3步,第4第5步后面我们出续集说明。

    1.实现数据劫持

    function defineData(data,key,val){
         Object.defineProperty(data,key,{
           get:function(){
               return val;
           },
           set:function(newVal){
               if(newVal === val){
                  return;
               }
               val = newVal;
           }
        })
    };
    

    2.收集依赖

    1. div标签中的引用
    2. span标签中的引用
    3. 计算属性getMsg中的引用
    4. watch监听

    我们将这四个依赖放入一个数组中,以便于管理触发

    let watcherList = [依赖1,依赖2,依赖3,依赖4];
    

    我上面说过,哪里使用了,哪里就需要收集,以便于通知.所以我们可以在使用属性值时触发的get回调中来进行收集.所以同理,当我们修改值时,触发通知的行为也应该在set函数中去执行.代码如下:

    function defineData(data,key,val){
         let watcherList = [];
         Object.defineProperty(data,key,{
           get:function(){
               watcherList.push(依赖);
               return val;
           },
           set:function(newVal){
               if(newVal === val){
                  return;
               }
               val = newVal;
               waterList.forEach(item=>{
                  // 通知所属依赖的每一项进行相应的修改
                  item.notice();
               })
           }
        })
    };
    

    在真实的Vue源码中,负责承担通知的角色正是watcher.也就是说,其实我们每一次收集使用了数据的依赖,实际上是把watcher进行了实例化,收集了watcher的实例化对象.这样当数据变化时,watcher的实例化对象就可以帮助我们进行通知修改.

    Vue对所有Key值的检测

    代码如下:

           class Observer{
            constructor(value){
              this.value = value;
              if(Array.isArray(value)){
                // 这里是对Array类型的单独处理,下篇会详细介绍
              }else{
                this.walk(value);
              } 
            }
    
            walk(obj){
              const keys = Object.keys(obj);
              keys.forEach(key=>{
                defineData(obj,key,obj[key]);
              });
            }
           }
    
           function defineData(data,key,val){
              // 递归判断,如果val仍然是object类型,则继续实例化Observer进行侦测
              if(Object.prototype.toString.call(val) === '[object Object]'){
                  new Observer(val);
              };
              let watcherList = [];
              Object.defineProperty(data,key,{
                enumerable:true, // 是否可枚举
                configurable:true, // 是否可修改和可删除,
                get:function(){
                  watcherList.push(new watcher);
                  return val;
                },
                set:function(newVal){
                  if(newVal === val){
                    return;
                  }
                  val = newVal;
                  waterList.forEach(item=>{
                    // 通知所属依赖的每一项进行相应的修改
                    item.notice();
                  })
                }
              })
           }
    
    • 资料来源:《深入浅出Vue.js》

    起源地下载网 » 你不知道的Vue双向数据绑定-新手篇

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元