Vuejs3 如何在单独的文件夹中注册自定义全局指令?

Vuejs3 how to register a custom global directive in a separate folder?

我想将我的全局自定义指令移动到一个单独的文件夹中并从文件中导入它,但是我在 Vue3 中没有这样做。

我得到了一个:

Uncaught TypeError: Cannot read properties of undefined (reading 'directive')

这是我的文件:

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

import VueGtag from 'vue-gtag'
import '@/plugins/gtag'


createApp(App)
  .use(
    VueGtag,
    {
      config: { id: process.env.VUE_APP_GOOGLE_ANALYTICS_ID },
      pageTrackerTemplate(to) {
        return {
          page_title: to.name,
          page_path: to.path,
        }
      },
    },
    router
  )
  .use(router)
  .mount('#app')

/plugin/gtag.js

import Vue from 'vue'
import { event } from 'vue-gtag'

const track = binding => () => {
  event('click', {
    event_category: binding.value.category,
    event_label: binding.value.label,
    value: 1,
  })
}

Vue.directive('track', {
  beforeMount(el, binding) {
    const trackFn = track(binding)

    el.addEventListener('click', trackFn)
    el.trackFn = trackFn
  },
  unmounted(el) {
    el.removeEventListener('click', el.trackFn)
  },
})

我知道,我的 gtag.jsimport Vue from 'vue' 是 Vuejs2,现在它应该用 { createApp } 导入。
但是我就是不知道,如何使用指令在Vuejs3中制作它?


编辑: 感谢@Leo 的解决方案:

plugins/gtag.js

import { event } from 'vue-gtag'

const track = binding => () => {
  event('click', {
    event_category: binding.value.category,
    event_label: binding.value.label,
    value: 1,
  })
}

const TrackDirective = {
  beforeMount(el, binding) {
    const trackFn = track(binding)

    el.addEventListener('click', trackFn)
    el.trackFn = trackFn
  },
  unmounted(el) {
    el.removeEventListener('click', el.trackFn)
  },
}

export default TrackDirective

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

import VueGtag from 'vue-gtag'
import TrackDirective from '@/plugins/gtag'

createApp(App)
.directive('track', TrackDirective)
  .use(
    VueGtag,
    {
      config: { id: process.env.VUE_APP_GOOGLE_ANALYTICS_ID },
      pageTrackerTemplate(to) {
        return {
          page_title: to.name,
          page_path: to.path,
        }
      },
    },
    router
  )
  .use(router)
  .mount('#app')

您需要直接在 app 变量上使用 directive

示例如下:

gtag.js

const TrackDirective = {
    beforeMount: (el, binding) => {
        el.addEventListener('click', () => {
            console.info('tracking')
        })
    }
}

export default TrackDirective

main.js

import TrackDirective from "./track";

const app = createApp(App)
app.directive('track', TrackDirective)
app.mount('#app')

一些组件

<template>
  <div v-track>
    click on this text
  </div>
</template>

参考:https://vuejs.org/guide/reusability/custom-directives.html#introduction