Skip to content

38.自定义指令的应用场景

1.1 指令的概念

Vue 除了内置指令之外,同时 Vue 也允许用户注册自定义指令来对 Vue 进行扩展。指令的目的在于可以将操作 DOM 的逻辑进行复用。

1.2 指令的生命周期

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

1.3 常见的指令编写

  • 图片懒加载 v-lazy

  • 防抖 v-debounce

  • 按钮权限 v-has

  • 拖拽指令 v-draggable (mousemove、 mouseup、 monsedown, dragenter、dragover、drop) 可视化拖拽编辑器

  • 点击事件处理 v-click-outside

html
<div v-click-outside="hide">
  <input type="text" @focus="show" />
  <div v-if="isShow">显示面板</div>
</div>
<div v-click-outside="hide">
  <input type="text" @focus="show" />
  <div v-if="isShow">显示面板</div>
</div>
js
Vue.directive(clickOutside, {
  bind(el, bindings, vnode) {
    el.handler = function (e) {
      if (!el.contains(e.target)) {
        let method = bindings.expression;
        vnode.context[method]();
      }
    };
    document.addEventListener("click", el.handler);
  },
  unbind(el) {
    document.removeEventListener("click", el.handler);
  },
});
Vue.directive(clickOutside, {
  bind(el, bindings, vnode) {
    el.handler = function (e) {
      if (!el.contains(e.target)) {
        let method = bindings.expression;
        vnode.context[method]();
      }
    };
    document.addEventListener("click", el.handler);
  },
  unbind(el) {
    document.removeEventListener("click", el.handler);
  },
});

Released under the MIT License.