Vue 3 | 自定义指令的新玩法

开门见山 

按照惯例,从上帝视角看一下自定义指令在 Vue 3 中发生了哪些改变:

  • 自定义指令的 API 改了名字,名字更贴近组件的生命周期

  • 自定义指令可以通过子组件的 v-bind="$attr"传递

Vue2.x 的自定义指令 

在 Vue 2 中,自定义指令通过以下可选的钩子去创建:

  • bind:当指令绑定在对应元素时触发。只会触发一次。

  • inserted:当对应元素被插入到 DOM 的父元素时触发。

  • update:当元素更新时,这个钩子会被触发(此时元素的后代元素还没有触发更新)。

  • componentUpdated:当整个组件(包括子组件)完成更新后,这个钩子触发。

  • unbind:当指令被从元素上移除时,这个钩子会被触发。也只触发一次。

来看个例子:

<h1 v-highlight="red">这是一串被高亮为红色的字</h1>
Vue.directive('highlight', {
  bind(el, binding, vnode) {
    el.style.background = binding.value;
  }
});

如上是一个很灵活的做法,通过指令传值的做法,可以供开发者根据使用场景的不同提供不同的参数,以达到不同的效果。

Vue 3 的自定义指令 

在 Vue 3 中,官方团队将自定义指令的 API 打造的更加“被人所熟悉”。正如你马上会看到的那样,尽管它们和组件的生命周期完全是两回事,但为了更有助于代码的可读性和风格统一,还是选择了比较接近的钩子名称:

  • bind => beforeMount

  • inserted => mounted

  • beforeUpdate: 新的钩子,会在元素自身更新前触发

  • update => 移除!

  • componentUpdated => updated

  • beforeUnmount: 新的钩子,当元素自身被卸载前触发

  • unbind => unmounted

所以,新版的自定义指令大概会长这个样子:

const NewDirective = {
  beforeMount(el, binding, vnode, prevVnode) {},
  mounted() {},
  beforeUpdate() {},
  updated() {},
  beforeUnmount() {},
  unmounted() {},
}

呐,上面的那个例子就会被改写成:

const app = Vue.createApp({});

app.directive('highlight', {
  beforeMount(el, binding, vnode) {
    el.style.background = binding.value;
  },
});

改了名字之后,是不是更好记了呢?

细节,注意细节 

Vue 3 是支持 fragments 的,也就是说,我们可以在一个组件中保留多个根节点。

<template>
  <li>你好</li>
  <li>我的</li>
  <li>粉丝</li>
</template>

于是自定义指令就遇到了一个新的问题:自定义指令有多个根节点?

因此,现在的自定义指令已经是 Virtual DOM 节点的一部分了。当组件上挂载了自定义指令时,它的钩子会作为一个外部属性传递进组件内,最终“落地”于组件的 this.$attr

这也就意味着,像下面这种直接在元素上挂载生命周期钩子的写法,即将同样适用于自定义指令的钩子:

<div @vnodeMounted="myHook"></div>

自定义指令向组件内传递 hook 的行为,和组件树中自上而下传递 prop 的行为是一致的。当一个组件给自身内部的元素绑定了 v-bind="$attr" 时,也会将自身的所有自定义指令都传递给自己的子元素。

“ 

如果想了解更详细的信息,请前往:https://v3.vuejs.org/guide/migration/custom-directives.html#overview(目前还没有中文版)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值