下面是我注册全局指令的代码:

app.directive("parse-code", (el: any, binding: any) => {
  // ......
  console.log("execute!!!");
});

似乎没有问题,控制台打印一下,看结果:

image

啥也没干却执行了两次,我最开始以为因为数据是异步的,可能导致指令被执行了两次,一个是没有获取时执行一次,一个时获取到了之后更新 DOM 时执行了一次。然而,并不是这样,还是执行了两次。于是查阅官方文档:

directive("parse-code", {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created() {
    console.log("d-created");
  },
  // 在元素被插入到 DOM 前调用
  beforeMount() {
    console.log("d-beforeMount");
  },
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted() {
    console.log("d-mounted");
  },
  // 绑定元素的父组件更新前调用
  beforeUpdate() {
    console.log("d-beforeUpdate");
  },
  // 在绑定元素的父组件
  // 及他自己的所有子节点都更新后调用
  updated() {
    console.log("d-updated");
  },
  // 绑定元素的父组件卸载前调用
  beforeUnmount() {
    console.log("d-beforeUnmount");
  },
  // 绑定元素的父组件卸载后调用
  unmounted() {
    console.log("d-unmounted");
  }
});

指令是有钩子函数的,但是我上面那种写法也是没有任何问题的,于是乎我就在 mounted 钩子函数里面写代码:

app.directive("parse-code", {
  mounted() {
    console.log("execute!!!");
  }
});

image

只执行了一次,问题完美解决。总结:写自定义指令最好写在钩子函数里面,以免多次执行。