老年大学系列:指令-vue2的指令在vue3中应该如何写?

205 阅读4分钟

今天准备整理下最近写的指令,方便以后粘贴复制,我个人常用的是vue2,虽然vue3有很大的性能提升,但对大公司来说,项目稳定优先度高于性能优化,而且很多项目也是vue2写的,更新迭代也是个巨大工作量。但进步总是需要的,而且vue3已经成为未来的趋势,很多公司也在应用,可能未来某天尤大大能够将vue2无缝衔接vue3,但这种被动的等待让未来充满不确定性,自己的未来还是应该自己主导不是。

vue3相对于vue2,改动还是比较大的,不然也不会跨一个大版本,改动大意味着学习压力骤升,那我自己来说,刚开始接触vue3第一想法就是:这是vue吗?这是我用的vue吗?咋好多写法都变了。迷茫和无力在看了文档又在几天之后因为没有实战应用忘得一干二净之后充斥我的脑海。次数多了,渐渐的甚至不想主动去学,我估计很多人也是这样的。

这次是久违的再次又接触了vue3,因为想着左右是整理,不如用vue3写demo。果然是距离产生美,隔一段时间没接触,我又开始了对vue3的追求。

废话不多说,开始正文(本文大部分内容来源于官方文档,因觉得文档内容太过分散,进行了总结,并加上一些自己的理解注释,毕竟进入老年大学的基本上vue2已经很熟悉了,相关功能就不再赘述,主要阐明vue3中对于vue2的功能用法)。

vue2的指令

在vue2中,我们一个简单的指令是由:指令名+指令注册钩子+执行逻辑。

一个简单的聚焦指令(组件内注册):

<input type="text" v-focus />
<script>
export default {
    directives: {
        'focus': { // 'focus'是指令名
            inserted(el) => { // 指令周期,vue2版本有:bind,inserted,update,componentUpdated,unbind,具体说明见下面:官方介绍
                el.focus()
            }
        }
    }
}
</script>

vue3的指令

在vue3中,一个简单的聚焦指令(新版改动了钩子和钩子入参,但就日常开发来说,了解钩子即可):

<input type="text" v-focus />
<script>
export default {
    directives: {
        'focus': {
            // vue3更改了部分钩子,用新的钩子替代,分别是created,beforeMount,mounted,beforeUpdate,updated,beforeUnmount,unmounted
            mounted(el) => { 
                el.focus()
            }
        }
    }
}
</script>

总结

在vue3中,一个简单的指令仍旧是:指令名+指令注册钩子+执行逻辑组成,不同的是修改了注册钩子和钩子的入参,但就日常开发来说,我们只需要注意钩子就行,新修改的钩子入参需要时看一看即可。

修改后的钩子同vue生命周期,更加好记了。(ps:我喜欢这个改动)

钩子的改动:

  • created - 新增!在元素的 attribute 或事件监听器被应用之前调用。
  • bind → beforeMount
  • inserted → mounted
  • beforeUpdate:新增!在元素本身被更新之前调用,与组件的生命周期钩子十分相似。
  • update → 移除!该钩子与 updated 有太多相似之处,因此它是多余的。请改用 updated
  • componentUpdated → updated
  • beforeUnmount:新增!与组件的生命周期钩子类似,它将在元素被卸载之前调用。
  • unbind -> unmounted

钩子入参的改动:

  • el - 保留。指令所绑定的元素,可以用来直接操作 DOM。

  • binding - 保留但有改动。绑定的对象

    • name:移除!指令名,不包括 v- 前缀。
    • value:保留。指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:保留。指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:移除!字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:保留。传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:保留。一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
    • instance:新增!使用指令的组件实例。
    • dir:新增!一个钩子对象,在注册指令时作为参数传递。例如简单聚焦指令,它的值见下图: 这是binding的dir的值.png
  • vnode - 当前绑定的元素的Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。里面的一些内容可见下图: image.png

  • oldVnode - 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

官方介绍

官方文档:指令从vue2到vue3的写法变化

官网文档:vue3的自定义指令写法