如何封装一个自定义指令兼容vue2、vue3

199 阅读1分钟

Vue 2 自定义指令中的生命周期钩子

  • bind: 指令绑定到元素时调用。
  • inserted: 元素插入到父节点时调用。
  • update: 组件更新时,指令所在组件的 VNode 更新时调用。
  • componentUpdated: 组件更新完成时调用。
  • unbind: 指令与元素解绑时调用。

Vue 3 自定义指令中中的生命周期钩子

  • beforeMount: 指令所在组件的挂载之前调用。
  • mounted: 指令所在组件的挂载完成时调用。
  • beforeUpdate: 指令所在组件的更新之前调用。
  • updated: 指令所在组件的更新完成时调用。
  • beforeUnmount: 指令所在组件的卸载之前调用。
  • unmounted: 指令所在组件的卸载完成时调用。

vue2和vue3自定义指令生命周期钩子映射关系

生命周期vue3vue
挂载之前beforeMountbind
挂载完成mountedinserted
组件更新前beforeUpdateupdate
组件更新完成updatedcomponentUpdated
组件卸载之前beforeUnmountunbind
组件卸载完成unmounted--

不得不说vue2的钩子函数命名真的不如vue3好记。所以这个时候我们封装一个createDirective函数

import type { App } from 'vue'

function createDirective({
  app,
  Vue,
  name,
  lifecycleHooks,
  version = 3,
}: {
  app: App
  Vue: any
  name: string
  lifecycleHooks: any
  version?: number
}) {
  if (version === 2) {
    const lifecycle = {
      bind: lifecycleHooks.beforeMount,
      inserted: lifecycleHooks.mounted,
      update: lifecycleHooks.beforeUpdate,
      componentUpdated: lifecycleHooks.updated,
      unbind: lifecycleHooks.beforeUnmount,
    }
    Vue.directive(name, lifecycle)
  } else {
    app.directive(name, lifecycleHooks)
  }
}

export default createDirective

下面我们写一个自定义指令

createDirective({
    app: app, // vue3的Vue实例
    Vue: Vue, // vue2的Vue构造函数
    version: vueVersion, // vue版本,可选值2|3
    name: 'tc', // 指令名称
    lifecycleHooks: {
      mounted: (el, binding) => {},
      beforeUnmount,
    },
  })