likes
comments
collection
share

Vue 指令与插件的使用指南

作者站长头像
站长
· 阅读数 1

指令 (Directives)

指令(Directives)是Vue模板中提供指令性操作的特殊标记,如v-modelv-showv-if等。自定义指令侧重于对普通DOM元素进行底层操作。

只有当所需功能只能通过直接的 DOM 操作来实现时,才应该使用自定义指令。其他情况下应该尽可能地使用 v-bind 这样的内置指令来声明式地使用模板,这样更高效,也对服务端渲染更友好。

文档

自定义指令v3

自定义指令v2

Vue 2 vs Vue 3

  • Vue2:
    • 全局注册:Vue.directive()
    • 局部注册:directives: { }
    • 钩子函数:bindinsertedupdatecomponentUpdatedunbind
    • 参数:elbindingvnodeoldVnode
  • Vue3: 在Vue 3中,自定义指令的钩子函数发生了变化,使其更好地与组件的生命周期保持一致.
    • 全局注册:app.directive()
    • 局部注册:directives: { }<script setup>中以v开头的驼峰式命名的变量。
    • 钩子函数:createdbeforeMountmountedbeforeUpdateupdatedbeforeUnmountunmounted
    • 参数:elbindingvnodeprevVnode

场景示例:

点击外部关闭弹窗: 可以通过自定义指令来监听点击事件,如果点击发生在弹窗外部,则关闭弹窗。

// Vue2
Vue.directive('click-outside', {
  bind(el, binding, vnode) {
    el.clickOutsideEvent = function(event) {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  unbind(el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
  },
});
// Vue3
const app = createApp({})

app.directive('click-outside', {
  // 在元素被插入到 DOM 前调用
  beforeMount(el,binding,vnode){
    el.clickOutsideEvent = function(event) {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  // 绑定元素的父组件卸载后调用
  unmounted(el){
    document.body.removeEventListener('click', el.clickOutsideEvent)
  }
})

插件 (Plugins)

插件是用于添加全局级别功能的Vue.js库。它们可以提供全局方法和属性、自定义指令、过滤器、过渡等。

文档

插件v3

插件v2

Vue 2 vs Vue 3

  • Vue2: 插件通过Vue.use()方法按照,并且可以接受选项。
  • Vue3: 插件安装方式同Vue2,但是Vue3的插件需要使用新的应用实例方法app.use()。因为Vue 3是基于应用实例创建的。

场景示例

  1. Vue Router: 用于页面路由管理的插件。
  2. Vuex: 用于状态管理的插件。
// Vue 2
Vue.use(VueRouter);
Vue.use(Vuex);

// Vue 3
const app = Vue.createApp({});
app.use(VueRouter);
app.use(Vuex);

理解Vue.use()

Vue.use()方法用于安装Vue插件。如果插件是一个对象,必须提供install方法。

如果插件是一个函数,它会被作为install方法。install方法调用时,会将Vue作为参数传入。

指令是否需要都封装成插件呢?

直接使用指令

指令可以直接在单个组件中定义和使用。这对于只有少数几个地方需要指令的情况来说非常方便。

将指令封装成插件

  • 复用性强:封装成插件后,指令可以在多个项目或者应用的多个部分重复使用,不仅减少了重复代码,也提高开发效率。
  • 易于管理:通过将插件发布到NPM,指令的更新和修复变得简单。通过版本控制和依赖管理,在多个项目中复用插件变得更加高效。
  • 扩展性:插件不仅可以包含指令,还可以包含组件、混入、过滤器等。

总结

如果你的指令只在少数几个地方使用,且与特定组件紧密相关,直接在组件内使用指令可能更合适。

如果你的指令具有广泛的适用性,或者你希望创建一个包含多个功能(如指令、组件等)的库,那么将指令封装成插件会是更好的选择。

封装成插件的方式提供了更好的复用性和扩展性,但也需要更多的配置和管理。直接使用指令则更加简单直接,但可能会导致代码重复和难以管理。选择哪种方式取决于你的具体需求和项目规模。

将指令封装成插件实现

将指令封装成插件的思路是,创建一个对象或函数,提供一个install方法。在install方法内部,你可以使用Vue.directive()app.directive来全局注册你的指令。

Vue2 vs Vue3

指令封装成插件的基本思路是相似的,但是由于Vue3引入了一些新的API和概念,因此实现上会有所不同

  • 注册方式:Vue 2使用Vue.directive进行全局注册,而Vue 3使用app.directive进行应用级别的注册。
  • 插件安装:Vue 2通过Vue.use()安装插件,Vue 3则需要在创建应用实例后,通过实例的use()方法安装。
  • 指令钩子函数:Vue 3在指令的钩子函数中引入了beforeMountmounted等新的钩子,替代了Vue 2中的bindinserted等钩子,以更好地与组件的生命周期保持一致。
  • 应用实例:在Vue 3中,你可以创建多个独立的应用实例,每个实例可以独立配置插件和指令。这意味着在同一个页面中,你可以有多个Vue应用运行,而每个应用可以有自己的插件配置,不会互相影响。这在Vue2中是不可能的。
const MyClickOutsidePlugin = {}

// Vue 2 插件示例
MyClickOutsidePlugin.install = (Vue) => {
  Vue.directive('click-outside', {
    bind(el, binding, vnode) {
      // 指令的钩子函数
    }
    // 其他钩子函数...
  });
}
// 使用插件
Vue.use(MyClickOutsidePlugin);


// Vue 3 插件示例
MyClickOutsidePlugin.install = (app) => {
  app.directive('click-outside', {
    beforeMount(el, binding, vnode) {
      // 指令的钩子函数
    }
    // 其他钩子函数...
  });
}

// 创建Vue应用并使用插件
const app = Vue.createApp({});
app.use(MyClickOutsidePlugin);