zoukankan      html  css  js  c++  java
  • vue中的数据双向绑定

    学习的过程是漫长的,只有坚持不懈才能到达到自己的目标。

    1.vue中数据的双向绑定采用的时候,数据劫持的模式。其实主要是用了Es5中的Object.defineProperty;来劫持每个属性的getter,和setter。这也正是Vue不兼容IE8以下的原因。

    2.Object.defineProerty();

    var obj = {};
            Object.defineProperty(obj,"hello",{
                enumerable: true,      //表示这个属性能够通过  for -- in 循环 (是否可枚举);
                configurable: true,   //表示这个属性能否用 delete 删除
                get(){  //获取属性值,说白了就是返回值
                    return this.val;
                },
                set(newVale){  //对属性的处理 (说白了: 就是在赋值的过程中提供一个方法来决定返回值)
                    this.val = newVale + 5; 
                    console.log(this.val); // 10
                }
            })
            obj.hello = 5;
            console.log(obj.hello) ;  // 10

    3.实现简单的双向绑定

    <input type="text" id="a">
    <div id="b"></div>
    <script type="text/javascript">
        var obj = {};
        Object.defineProperty(obj,`value`,{
            enumerable: true,
            configurable: true,
            get(){
                return this.val;
            },
            set(newValue){
                document.getElementById(`b`).innerText = newValue;
                this.val = newValue;  //66
            }
        });
    
        document.getElementById(`a`).addEventListener(`input`,function(event){
            var text = event.target.value; //66
            obj.value = text;
        },false)
        
    </script>

    这种方式简单粗暴,直接通过操作DOM完成绑定。我想,肯定有人会认为,你这样写,还不如在input事件中直接对Id为B的DOM元素赋值,这样不是多此一举吗?请看下面在框架中我们该如何实现。

    4.实现简单的  v-model

    首先我们需要获取文档中的真实元素节点也就是VUE中实列话VUE中元素挂载点(el);在通过createDocumentFragment创建文档碎片,解析操作完毕后,把碎片放置在DOM中。
    <div id="app">
        <input type="text" id="a" v-model="text">
        {{text}}
    </div>
     <script type="text/javascript">
        function Model(node, vm) {
            if(node) {this.$frag = this.nodeToFragment(node, vm);
                return this.$frag;
            }
        }
        Model.prototype = {
            construtor:'Model',
            nodeToFragment: function(node, vm) {
                var self = this;
                var frag = document.createDocumentFragment();
                var child;
    
                while(child = node.firstChild) {
                    self.moelElement(child, vm);
                    frag.appendChild(child); 
    // 将所有子节点添加到fragment中,child是指向元素首个子节点的引用。
    // 将child引用指向的对象append到父对象的末尾,原来child引用的对象就跳到了frag对象的末尾,
    // 而child就指向了本来是排在第二个的元素对象。如此循环下去,链接就逐个往后跳了
                }
                return frag;
            },
            moelElement: function(node, vm) {
                var reg = /{{(.*)}}/; //匹配 {{}} () 获取匹配到的值
    
                //节点类型为元素
                if(node.nodeType === 1) {
                    var attr = node.attributes;
                    // 解析属性
                    for(var i = 0; i < attr.length; i++ ) {
                        if(attr[i].nodeName == 'v-model') {
                            var name = attr[i].nodeValue; // 获取v-model绑定的属性名
                            node.addEventListener('input', function(e) {
                                // 给相应的data属性赋值,进而触发该属性的set方法
                                vm.data[name]= e.target.value;
                            });
                            node.value = vm.data[name]; // 将data的值赋给该node
                            node.removeAttribute('v-model');
                        }
                    };
                }
                //节点类型为text
                if(node.nodeType === 3) {
                    if(reg.test(node.nodeValue)) {
                        var name = RegExp.$1; // 获取匹配到的字符串  () 正则中的分组。通过$1获取第一个分组
                        name = name.trim();
                        node.nodeValue = vm.data[name]; // 将data的值赋给该node
                    }
                }
            },
        }
        function Vue(options) {
            this.data = options.data;
            var data = this.data;
            var id = options.el;
            var dom =new Model(document.getElementById(id),this);
            // 编译完成后,将dom返回到app中
            document.getElementById(id).appendChild(dom);
        }
        var vm = new Vue({
            el: 'app',
            data: {
                text: 'hello world'
            }
        });
    </script>

    到这里主要是学习了VUE中对指令的处理。到这儿你就可以添加只自定义的指令了。同时也明白自定义指令是如何实现的了。当然数据的双向绑定是还没有实现的。

     




















  • 相关阅读:
    eclipse快捷键 Eclipse快捷键 10个最有用的快捷键
    ssh之雇员管理系统(5)将struts+spring整合2
    ssh之雇员管理系统(4)改进的hibernate测试
    java中常常建包时,这些包具体是什么意思呢?+项目开发流程、实战
    ssh之雇员管理系统(1)spring测试
    JUnit4概述
    ssh之雇员管理系统(5)添加struts测试
    SQl查询数据库表名、表的列名
    关于人脉大PK的二三事 推荐的方法
    JavaScript有用的代码(ie,save)
  • 原文地址:https://www.cnblogs.com/createGod/p/6833561.html
Copyright © 2011-2022 走看看