• vue简单源码手写,实现基本的模板解析,v-text,v-html,v-on:click,@click基本语法指令


    前言

    具体可以看bilibili的视频https://www.bilibili.com/video/BV15D4y1o73Z

    源码可以自己下载,和视频基本一样

    下载地址:https://github.com/superBiuBiuMan/vue-write-self

    笔记

    第五集的时候为什么设置Dep.target = this后又置为空

    获取旧值表达式为以下
    getOldValue(){
        Dep.target = this;
        const oldvalue = compileUtil.getValue(this.expr,this.vm.$data);
        Dep.target = null;
        return oldValue;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 一开始我看到这个,很奇怪,觉得这样子会可以让Observer成功添加到watcher吗?
      • 是的,的确可以,在Observer当中,我们通过defineProperty为data当中的每一个属性添加了set和get方法,也就是说
        我们每次读取值也会触发set,设置值则会触发get,所以当我们初始化页面编译模板的时候,就会触发set,从而向对应的dep添加对应的watcher
    • 所以这就解释了调用compileUtil.getValue()之后就会添加watcher的问题
    • 那么为什么需要设置Dep.target = null取消呢?
      • 在我们触发更新的时候,通过set设置了新值,后面肯定需要显示在页面,所以我们肯定需要调用get方法,此时如果我们不设置Dep.target = null,那么就会导致对应的watcher被重复添加了

    setValue为对象的时候会报错的解决

    • 因为如果是person.name的时候,我们必须要返回上一次获取的值作为vm.$data,才可以循环获取到最终的name值,老师写的vm.$data不会返回上一次获取到的值,所以就会导致报错
    • 说通俗点就是老师写的那个方法只适合一层对象,不适合多层对象,想要适合多层对象,就需要循环获取值
        /*设置表达式的值*/
        setVal(expr,vm,inputValue){
            //当设置的值为person.fav这种多层对象的时候,会报错
            //expr.split(".").reduce((preData,currentValue)=>{
            //    console.log(preData)
            //    preData[currentValue] = inputValue;
            //},vm.$data)
            //所以下面是修复
            expr.split(".").reduce((preData,currentValueKey)=>{
                if(Object.prototype.toString.call(preData[currentValueKey]) === '[object Object]'){
                    return preData[currentValueKey];
                }else{
                    preData[currentValueKey] = inputValue;
                }
            },vm.$data)
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    总结

    • vue通过数据劫持和发布者订阅者模式,通过Object.defineProperty()当中的setter和getter来劫持数据变动,从而达到在数据变动的时候通知相应的dep去执行对应的watcher

    • 我们在创建vue则会执行模板的解析,也就是compile,在解析编译时候,为会为每一个使用到的字段创建相应的watcher,并添加到对应的Dep当中,在我们通过Observer劫持监听所有属性的时候,是通过Object.defineProperty的setter和getter来实现的,当我们更新数据的时候,会通知dep去执行里面的watcher

    数据绑定原理图-老师

    数据绑定原理图-自己

  • 相关阅读:
    php高级 TP+Redis实现发布订阅和消息推送案例实战
    [蓝桥杯 2013 省 AB] 错误票据
    centos7.6 MySQL 5.5 主从同步配置
    数据结构与算法(七) 二分法
    【Docker】Compose容器编排:微服务实战
    博士新生应该懂得哪些道理? - 易智编译EaseEditing
    rpc依赖安装
    js事件:
    【弹性盒子】制作一个动画卡片
    可删除背包(计数类)=>转移数组进行展开:ABC321F
  • 原文地址:https://blog.csdn.net/u014582342/article/details/127829265