码迷,mamicode.com
首页 > 其他好文 > 详细

vue之双绑实现

时间:2018-04-24 21:55:15      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:dom   绑定   date()   direct   ==   query   init   set   false   

// 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];
  }

 

vue之双绑实现

标签:dom   绑定   date()   direct   ==   query   init   set   false   

原文地址:https://www.cnblogs.com/flxy-1028/p/8933399.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!