vue之双绑实现

Posted ypm_wbg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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];
  }

 

以上是关于vue之双绑实现的主要内容,如果未能解决你的问题,请参考以下文章

jQuery之双下拉框

vue组件化开发实战 - 实现简易ElementUI的Form表单组件

VSCode自定义代码片段1——vue主模板

VSCode自定义代码片段——.vue文件的模板

STM32H7教程第92章 STM32H7的FDCAN总线应用之双FDCAN实现(支持经典CAN)

VSCode自定义代码片段(vue主模板)