美文网首页vue
vue解析6-其他

vue解析6-其他

作者: 百里哈哈 | 来源:发表于2020-04-15 23:27 被阅读0次

指令

示例

<template>
    <div>
        this is a directive
        <div id="hook-arguments-example" v-demo:foo.a.b="msg"></div>
        <p style="margin-bottom: 20px; border-bottom: 1px solid red;">
            do some thing <span @click="chgMsg">chg the msg</span>
        </p>
    </div>
</template>

<script>

const demoDirect = {
    bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML =
        'name: '       + s(binding.name) + '<br>' +
        'value: '      + s(binding.value) + '<br>' +
        'expression: ' + s(binding.expression) + '<br>' +
        'argument: '   + s(binding.arg) + '<br>' +
        'modifiers: '  + s(binding.modifiers) + '<br>' +
        'vnode keys: ' + Object.keys(vnode).join(', ')
    },
    inserted: function () {},
    update: function () {
        console.log('to update')
    },
    componentUpdated: function () {},
    unbind: function () {}
}
export default {
    data () {
        return {
            msg: 'hello'
        }
    },
    directives: {
        'demo' : demoDirect
    },
    methods: {
        chgMsg() {
            console.log('click msg')
            this.msg = 'wowow' + Date.now();
        }
    }
}
</script>

我们知道通过指令可以在元素生命周期如挂载、更新或者卸载的时候做一些处理。

通过update方法我们可以看到其中的如bind、update方法的调用
代码如下

function _update (oldVnode, vnode) {
  var isCreate = oldVnode === emptyNode;
  var isDestroy = vnode === emptyNode;
  var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);
  var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);

  var dirsWithInsert = [];
  var dirsWithPostpatch = [];

  var key, oldDir, dir;
  for (key in newDirs) {
    oldDir = oldDirs[key];
    dir = newDirs[key];
    if (!oldDir) {
      // new directive, bind
      callHook$1(dir, 'bind', vnode, oldVnode);
      if (dir.def && dir.def.inserted) {
        dirsWithInsert.push(dir);
      }
    } else {
      // existing directive, update
      dir.oldValue = oldDir.value;
      dir.oldArg = oldDir.arg;
      callHook$1(dir, 'update', vnode, oldVnode);
      if (dir.def && dir.def.componentUpdated) {
        dirsWithPostpatch.push(dir);
      }
    }
  }

  if (dirsWithInsert.length) {
    var callInsert = function () {
      for (var i = 0; i < dirsWithInsert.length; i++) {
        callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode);
      }
    };
    if (isCreate) {
      mergeVNodeHook(vnode, 'insert', callInsert);
    } else {
      callInsert();
    }
  }

  if (dirsWithPostpatch.length) {
    mergeVNodeHook(vnode, 'postpatch', function () {
      for (var i = 0; i < dirsWithPostpatch.length; i++) {
        callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode);
      }
    });
  }

  if (!isCreate) {
    for (key in oldDirs) {
      if (!newDirs[key]) {
        // no longer present, unbind
        callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy);
      }
    }
  }
}

v-model

// transform component v-model data into props & events
  if (isDef(data.model)) {
    transformModel(Ctor.options, data);
  }
// transform component v-model info (value and callback) into
// prop and event handler respectively.
function transformModel (options, data) {
  var prop = (options.model && options.model.prop) || 'value';
  var event = (options.model && options.model.event) || 'input'
  ;(data.attrs || (data.attrs = {}))[prop] = data.model.value;
  var on = data.on || (data.on = {});
  var existing = on[event];
  var callback = data.model.callback;
  if (isDef(existing)) {
    if (
      Array.isArray(existing)
        ? existing.indexOf(callback) === -1
        : existing !== callback
    ) {
      on[event] = [callback].concat(existing);
    }
  } else {
    on[event] = callback;
  }
}

示例代码

<input  type="text"
                :value="value"
                @input="value = $event.target.value"
            >
        <input v-model="name" type="text">

对应的render函数

                t("input",
                                { attrs: { type: "text" }, domProps: { value: e.value              }, 
                                on: { input: function (n) { e.value = n.target.value } } }),
                t("input",
                                { directives: [{ name: "model", rawName: "v-model", value: e.name, expression: "name" }], 
                                attrs: { type: "text" }, domProps: { value: e.name }, 
                                on: { input: function (n) { n.target.composing || (e.name = n.target.value) } } })])



相关文章

网友评论

    本文标题:vue解析6-其他

    本文链接:https://www.haomeiwen.com/subject/zfchvhtx.html