zoukankan      html  css  js  c++  java
  • vue之双绑实现

    // html
    
    <body>
      <div id="app">
        <input type="text" v-model="number">
        <input type="text" v-model="num">
        <input type="button" v-click="increment" value="加1">
        <input type="button" v-click="increment" value="加2">
        <h3 v-bind="number"></h3>
        <h3 v-bind="num"></h3>
      </div>
    </body>
    // js vue的实例
    
      window.onload = function () {
        var app = new Vue({
          el: '#app',
          data: {
            number: 0,
            num: 5,
          },
          methods: {
            increment: function () {
              this.number++;
              this.num++;
            },
          }
        })
      }
    // vue的构造函数
    
      function Vue(options) {
        this._init(options);
      }
      Vue.prototype._init = function (options) {
        this.$options = options;
        this.$el = document.querySelector(options.el);
        this.$data = options.data;
        this.$methods = options.methods;
    
        this._binding = {};
        this._obverse(this.$data);
        this._complie(this.$el);
      }
      Vue.prototype._obverse = function (obj) {
        var _this = this
        for (let key in obj) {
          if (obj.hasOwnProperty(key)) {
            this._binding[key] = {
              _directives: []
            };
            let value = obj[key];
            if (typeof value === 'object') {
              this._obverse(value);
            }
            let binding = this._binding[key];
            Object.defineProperty(this.$data, key, {
              enumerable: true,//目标属性是否可以被枚举。true | false
              configurable: true, //目标属性是否可以被删除或是否可以再次修改特性 true | false
              get: function () {
                return value;
              },
              set: function (newVal) {
                if (value !== newVal) {
                  value = newVal;
                  binding._directives.forEach(function (item) {
                    item.update();
                  })
                }
              }
            })
          }
        }
      }
     
    
      Vue.prototype._complie = function (root) {
        var _this = this;
        var nodes = root.children;
        for (let i = 0; i < nodes.length; i++) {
              let node = nodes[i];
          if (node.children.length) {
            _this._complie(node);
          }
    
          if (node.hasAttribute('v-click')) {
            node.onclick = (function () {
              var attrVal = nodes[i].getAttribute('v-click');
              return _this.$methods[attrVal].bind(_this.$data);
            })(i);
          }
    
          if (node.hasAttribute('v-model') && (node.tagName == 'INPUT' || node.tagName == 'TEXTAREA')) {
            node.addEventListener('input', (function() {
              var attrVal = node.getAttribute('v-model');
              _this._binding[attrVal]._directives.push(new Watcher(
                'input',
                node,
                _this,
                attrVal,
                'value'
              ))
              return function () {
                _this.$data[attrVal] = nodes[key].value;
              }
            })());
          }
          if(node.hasAttribute("v-bind")){
            var attrVal = node.getAttribute('v-bind');
            _this._binding[attrVal]._directives.push(new Watcher(
                'text',
                node,
                _this,
                attrVal,
                'innerHTML'
              ))
          }
        }
      }
      function Watcher(name, el, vm, exp, attr) {
        this.name = name;         //指令名称,例如文本节点,该值设为"text"
        this.el = el;             //指令对应的DOM元素
        this.vm = vm;             //指令所属myVue实例
        this.exp = exp;           //指令对应的值,本例如"number"
        this.attr = attr;         //绑定的属性值,本例为"innerHTML"
    
        this.update();
      }
      Watcher.prototype.update = function () {
        this.el[this.attr] = this.vm.$data[this.exp];
      }
  • 相关阅读:
    [CF920E] Connected Components?
    [CF981E] Addition on Segments
    [BZOJ2152] 聪聪可可
    [CF1355E] Restorer Distance
    [CF1101D] GCD Counting
    [CF827C] DNA Evolution
    [HNOI2008] 明明的烦恼
    [CF712D] Memory and Scores
    [CF609E] Minimum spanning tree for each edge
    后缀自动机应用小结 I
  • 原文地址:https://www.cnblogs.com/flxy-1028/p/8933399.html
Copyright © 2011-2022 走看看