ITPub博客

首页 > IT职业 > IT图书 > 动手撸起来,ES6实现简单的vue

动手撸起来,ES6实现简单的vue

IT图书 作者:boss_ch 时间:2021-09-09 09:02:09 0 删除 编辑

//模板






  1. v-model:
  2. v-text:
  3. v-show :hide or show
  4. v-on:click:

//逻辑

//declaring directives
var Directives = {
    text(el, value) {
        el.textContent = value || ''
      },
      show(el, value) {
        el.style.display = value ? '' : 'none'
      },
      on: {
        update(el, handler, event, directive) {
          if (!directive.handlers) {
            directive.handlers = {}
          }
          var handlers = directive.handlers
          if (handlers[event]) {
            el.removeEventListener(event, handlers[event])
          }
          if (handler) {
            handler = handler.bind(el);
            el.addEventListener(event, handler);
            handlers[event] = handler;
          }
        }
      },
      model: {
        bind(el, key, directive, seed) {
            el.addEventListener('keyup', () => seed.$data[key] = el.value);
          },
          update(el, value) {
            el.value = value;
          }
      }
  }
  //difine utils
var Utils = {
  cloneAttributes(attributes) {
      return Array.from(attributes).map(attribute => {
        return {
          name: attribute.name,
          value: attribute.value
        }
      })
    },
    parseDirective(attr) {
      if (!attr.name.includes(prefix)) return;
      var noprefix = attr.name.slice(prefix.length + 1),
        argIndex = noprefix.indexOf(':'),
        dirname = argIndex === -1 ? noprefix : noprefix.slice(0, argIndex),
        def = Directives[dirname],
        arg = argIndex === -1 ? null : noprefix.slice(argIndex + 1);
      var exp = attr.value,
        key = exp.trim();
      return def ? {
        attr: attr,
        key: key,
        definition: def,
        argument: arg,
        update: typeof def === 'function' ? def : def.update,
        bind: typeof def === 'function' ? null : def.bind ? def.bind : null
      } : null;
    }
};
//prefix
var prefix = 'v',
  selector = Object.keys(Directives).map(d => `[${prefix}-${d}]`).join();
//constructor
function Vue(el, opts = {}) {
  var root = self.$el = document.querySelector(el),
    els = root.querySelectorAll(selector),
    _bindings = {};
  this.$opts = opts;
  this.$data = {}; //export api
  this.processNode(els, _bindings);
  this.initData(_bindings);
}
//handle nodes
Vue.prototype.processNode = function(els, _bindings) {
    els.forEach(el => {
      Utils.cloneAttributes(el.attributes).forEach(attr => {
        var directive = Utils.parseDirective(attr);
        directive && this.bindDirective(el, _bindings, directive)
      });
    });
  }
  //attribute remove and directive binding
Vue.prototype.bindDirective = function(el, _bindings, directive) {
    var self = this;
    el.removeAttribute(directive.attr.name);
    var key = directive.key,
      binding = _bindings[key];
    if (!binding) {
      _bindings[key] = binding = {
        value: undefined,
        directives: []
      }
    }
    directive.el = el;
    binding.directives.push(directive);

    if (directive.bind) {
      directive.bind(el, key, directive, self);
    }
    if (!self.$data.hasOwnProperty(key)) {
      self.bind(key, binding);
    }
  }
  //set and get
Vue.prototype.bind = function(key, binding) {
  Object.defineProperty(this.$data, key, {
    set: value => {
      binding.value = value;
      binding.directives.forEach(directive => {
        directive.update(
          directive.el,
          value,
          directive.argument,
          directive,
          this
        )
      })
    },
    get: () => binding.value,
  })
};
//initial
Vue.prototype.initData = function(_bindings) {
  for (let variable in _bindings) {
    this.$data[variable] = this.$opts[variable];
  }
};

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/97/viewspace-2798803/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: git基本使用
请登录后发表评论 登录
全部评论

注册时间:2019-02-22

  • 博文量
    83
  • 访问量
    465