深层解读Vue—Vue双向绑定

5 篇文章 0 订阅

首先我们要知道Vue双向绑定的几个概念

1.comple(解析器):主要是用来解析你的节点、子节点、属性(w-on: ,w-html,w-model)
2.observe(观察者):主要是来对data中的属性进行监听( Object.defineProperty)
3.watcher(订阅者):主要是用来接受数据变化,进而实现视图更新
好了直接撸代码吧
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./index.js"></script>
</head>
<body>
    <div id="myApp">
        <input type="button" value="按钮" w-on:click="fn">
        <input type="text" style="width:400px" w-model="advice">
        <div w-text="advice"></div>
        <div w-html="advice"></div>
    </div>
</body>
<script>
    var vm = new Wang({
        el: "#myApp",
        data: {
            advice: "<a href='javaScript:;'>加油吧少年</a>"
        },
        methods: {
            fn() {
                this.advice += "!";
            }
        }
    })
</script>
</html>

index.js

function Wang(options){
    this.$el = document.querySelector(options.el);
    this.$data = options.data;
    this.$methods = options.methods;
    this.binding = {};
    this.observer();
    this.compile(this.$el);
}
Wang.prototype.observer=function(){
    var value = '';
    Object.keys(this.$data).forEach(key=>{
        value = this.$data[key];
        this.binding[key] = [];
        var binding =  this.binding[key];
        Object.defineProperty(this.$data,key,{
            get(){
                return value;
            },
            set(v){
                if(v!==value){
                    value = v;
                    binding.forEach(item=>{//这里binding是浅拷贝
                        item.update();
                    })
                }
            }
        })
    })
}
Wang.prototype.compile = function(el){
    var nodes =el.children;
    for(var i =0 ;i<nodes.length;i++){
        var node = nodes[i];
        if(node.children.length>0){
            this.compile(node);
        }
        if(node.hasAttribute('w-on:click')){
            var attrVal = node.getAttribute('w-on:click');
            node.addEventListener("click",this.$methods[attrVal].bind(this.$data))
        }
        if(node.hasAttribute('w-html')){
            var attrVal = node.getAttribute('w-html');
            this.binding[attrVal].push(new Watcher(node,"innerHTML",this,attrVal))
        }
        if(node.hasAttribute('w-text')){
            var attrVal = node.getAttribute('w-text');
            this.binding[attrVal].push(new Watcher(node,"innerText",this,attrVal))
        }
        if(node.hasAttribute('w-model')){
            var attrVal = node.getAttribute('w-model');
            node.addEventListener('input',((i)=>{
                this.binding[attrVal].push(new Watcher(node,"value",this,attrVal));
                return  ()=>{
                    this.$data[attrVal] = nodes[i].value;
                }
            })(i))
        }
    }
}
function Watcher(el,attr,vm,value){
    this.el = el;
    this.attr = attr;
    this.vm = vm;
    this.value = value;
    this.update();
}
Watcher.prototype.update=function(){
    this.el[this.attr] = this.vm.$data[this.value]
}

别急还有个简单的双向绑定让你更好的理解Object.defineProperty

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./index.js"></script>
</head>
<body>
    <input type="text" id="tet">
    <div id="box"></div>
</body>
<script>
   var oText = document.getElementById("tet");
   var oDiv = document.getElementById("box");

   var name="隔壁老王"
   var obj = {
       name
   }
   Object.defineProperty(obj,"name",{
       get(){
           return name;
       },
       set(v){
            oText.value = oDiv.innerHTML = v
       }
   })
   oText.value = oDiv.innerHTML = obj.name;
   oText.onkeyup=function(){
       obj.name = this.value;
   }
</script>
</html>

最好感谢张培跃老师的原文指导

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值