Skip to content

自定义指令

  • bind 调用一次,初始化用
  • inserted 节点插入父结点调用, 父节点不一定插入在文档中
  • update 所在组更新时和(子组件更新之前)
  • componentUpdated 所在组和子组件更新
  • unbind 解绑
js
// <input v-focus>

// 注册一个全局自定义指令 `v-focus`
Vue.directive("focus", {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus();
  },
});

directives: {
  focus: {
    inserted: function (el) {
      // 聚焦元素
      el.focus();
    },
  }
}

简写

  • bind 和 update 触发相同行为
js
// <div v-color-swatch="{ color: 'white' }"></div>
Vue.directive("color-swatch", function (el, binding) {
  el.style.backgroundColor = binding.value.color;
});

input 下划线

js
import { on, off, addClass, removeClass } from "@/utils";

const temp = [];

export const inputBorder = {
  inserted(el, binding) {
    const { className } = binding.value;
    const elm = el.querySelector("input");
    const focusEvent = (e) => addClass(el, className);
    const blurEvent = (e) => removeClass(el, className);
    on(elm, "focus", focusEvent);
    on(elm, "blur", blurEvent);
    temp.push({
      el,
      elm,
      events: {
        focusEvent,
        blurEvent,
      },
    });
  },
  unbind(el) {
    const index = temp.findIndex((item) => item.el === el);
    if (index > -1) {
      const [item] = temp.splice(index, 1);
      const { elm, events } = item;
      off(elm, "focus", events.focusEvent);
      off(elm, "blur", events.blurEvent);
    }
  },
};

声音预加载

js
Vue.directive("preload", {
  inserted(el) {
    el.addEventListener("click", () => {
      sound.play(bufferAudo.buffer);
    });
  },
});

clipboard

js
import Clipboard from "clipboard";
import { Message } from "element-ui";

function onSuccess() {
  Message({
    type: "success",
    message: "复制成功,按ctrl+v可直接使用!",
  });
}
function onError() {
  Message({
    type: "warning",
    message: "复制失败!",
  });
}

export const clipboard = {
  bind(el, bingind, vnode) {
    el._vClipBoard_success = onSuccess;
    el._vClipBoard_error = onError;
    switch (bingind.arg) {
      case "success":
        el._vClipBoard_success = bingind.value;
        break;
      case "error":
        el._vClipBoard_error = bingind.value;
        break;
      default: {
        const clip = new Clipboard(el, {
          text: () => bingind.value,
          action: () => (bingind.arg === "cut" ? "cut" : "copy"),
        });
        // el.dataset.clipboardText = bingind.value;
        clip.on("success", (e) => {
          /* {action,text,trigger} = e */
          const callback = el._vClipBoard_success;
          callback && callback(e);
        });
        clip.on("error", (e) => {
          const callback = el._vClipBoard_error;
          callback && callback(e);
        });
        el._vClipBoard = clip;
      }
    }
  },
  update(el, bingind) {
    // el.dataset.clipboardText = bingind.value;
    if (bingind.arg === "success") {
      el._vClipBoard_success = bingind.value;
    } else if (bingind.arg === "error") {
      el._vClipBoard_error = bingind.value;
    } else {
      el._vClipBoard.text = function () {
        return bingind.value;
      };
      el._vClipBoard.action = () => (bingind.arg === "cut" ? "cut" : "copy");
    }
  },
  unbind(el, bingind) {
    if (bingind.arg === "success") {
      delete el._vClipBoard_success;
    } else if (bingind.arg === "error") {
      delete el._vClipBoard_error;
    } else {
      el._vClipBoard.destroy();
      delete el._vClipBoard;
    }
  },
};

在 MIT 许可下发布