手把手教你快速开发一款 Vue.js 3 插件

2023-11-23 13:15:06 浏览数 (1)

在 Vue.js 中,插件(Plugins)是一种能为 Vue.js 添加全局功能的工具代码。Vue.js 3 插件没有严格定义的使用范围,但是插件的应用场景主要包括以下几种。

  • 通过 app.component() 和 app.directive() 注册一个或多个全局组件或自定义指令。
  • 通过 app.provide() 使一个资源可被注入整个应用。
  • 向 app.config.globalProperties 中添加一些全局实例属性或方法。
  • 一个可能包含上述三种功能的功能库,例如 Vue Router 。

以下是一些常见的 Vue.js 插件。

  • Vue Router: 用于管理应用程序的路由和导航的官方插件。它允许在单页应用中进行页面之间的导航和路由。
  • Vuex: 用于管理应用程序的状态和状态变化的官方插件。它提供了一个集中式的状态管理系统,用于处理数据的共享和同步。
  • vue-i18n: 用于处理国际化和本地化的插件,允许在应用程序中轻松管理多语言文本。
  • Element UI、Ant Design Vue: 是流行的 Vue.js UI 组件库,提供了丰富的预制组件,以简化用户界面的构建。

当我们在编写 Vue.js 3 插件时,通常有以下两种编写方式。

  • 对象类型:一个对象,必须包含一个 install 函数,该函数会在安装插件时执行。
  • 函数类型:一个function,这个函数会在安装插件时自动执行。

下面将分别介绍对象类型和函数类型插件的编写方式。

01

对象类型的插件

下面先介绍通过对象类型的方式来编写一个添加全局属性的Vue.js 3插件。新建01_learn_component项目,并在src目录下新建plugins文件夹,然后在该文件夹下新建plugins_object.js文件。

代码语言:javascript复制
plugins_object.js文件,代码如下所示:
export default { // 1.必须包含一个 install 函数
  install(app) {
    // 2.插件的作用是给app实例添加一个全局属性:$name
    app.config.globalProperties.$name = "coderwhy"
  }
}

可以看到,该对象类型插件导出一个必须包含一个 install 函数的对象,该函数会在 app.use 安装插件时执行。接着,修改main.js文件来安装该插件,代码如下所示(省略了样式):

代码语言:javascript复制
......
import pluginObject from './plugins/plugins_object'
import App from './05_插件的使用/App.vue'
let app =createApp(App)
......
app.use(pluginObject); // 3.安装插件时,会执行插件的install函数
app.mount('#app')

可以看到,这里我们先导入了pluginObject函数,接着使用app.use函数来安装该插件。

下面我们使用一下该插件。在01_learn_component项目的src目录下新建05_插件的使用文件夹,然后在该文件夹下新建App.vue组件。

App.vue组件,代码如下所示:

代码语言:javascript复制
<template>
  <div style="border:1px solid #ddd;margin:4px">App组件</div>
</template>
<script>
 import { getCurrentInstance } from "vue";
 export default {
    setup() {
      const instance = getCurrentInstance(); // 1.拿到组件实例,相当于 this
      // 2.通过组件实例访问全局属性: $name
      console.log("setup name=", instance.appContext.config.globalProperties.$name);
    },
    mounted() {
      //2.通过this访问全局属性: $name
      console.log("mounted name=", this.$name);
    }
 }
</script>

可以看到,我们在setup函数中,通过调用getCurrentInstance API来访问内部组件实例。因为在setup函数中不能使用this来获取组件实例。

接着,我们通过instance.appContext.config.globalProperties来获取app实例上的全局属性。然后将在pluginObject插件中添加到全局属性$name的值打印出来。

需要注意的是:添加到全局的属性,我们可以直接通过this来访问。例如,在上述的mounted生命周期中,我们直接通过this来访问全局属性。

最后,修改main.js程序入口文件,将导入的App.vue组件改为05_插件的使用/App.vue路径下的App.vue组件。

保存代码,在浏览器中显示的效果如图所示。控制台可以正常打印pluginObject插件添加的全局属性$name的值。

02

函数类型的插件

在编写Vue.js 3插件时,除了支持用对象类型编写,还支持用函数类型编写。下面将使用函数类型来编写上述插件。在plugins文件夹下新建plugins_function.js文件。

plugins_function.js文件,代码如下所示:

代码语言:javascript复制
export default function(app) {
  // 1.插件是给app实例添加一个全局属性:$name  
  app.config.globalProperties.$name = "coderwhy"
  // todo... 可以继续给app实例添加全局的属性、方法、指令、组件、mixin等
}

可以看到,该函数类型插件必须导出一个接收app实例的函数,该函数会在app.use安装插件时自动执行。接着,修改main.js文件来安装该插件,代码如下所示:

代码语言:javascript复制
......
import pluginFunction from './plugins/plugins_function'
import App from './05_插件的使用/App.vue'
let app =createApp(App)
......
// app.use(pluginObject);
app.use(pluginFunction); // 4.用app的use函数来安装插件
app.mount('#app')

可以看到,这里先导入了pluginFunction函数,然后使用app.use函数来安装该插件。

安装好插件后,保存代码,在浏览器中运行代码,即可看到与上面案例相同的效果。

03

开发 Vue Toast 插件

在前端开发中,我们经常会遇到冒吐司(Toast)的功能。

下面将通过以下四个步骤带着大家把 Toast 功能单独封装成一个 Vue.js 的插件,并将其命名为 vue-toast。

第一步: 创建插件文件(vue-toast.js)。

首先,在plugins文件夹下新建vue-toast.js文件,代码如下图所示:

代码语言:javascript复制
import { render, createVNode } from 'vue';
import ToastComponent from './Toast.vue';


const VueToast = {
  install(app) {
    
    app.config.globalProperties.$toast = (message, type = 'info', duration = 3000) => {
      const container = document.createElement('div');
      // 1.创建一个挂载容器
      document.body.appendChild(container);
      // 2.创建虚拟节点
      let vm = createVNode(ToastComponent);
      // 3.渲染虚拟节点
      render(vm, container);
      // 4.调用 ToastComponent 组件暴露的方法显示 Toast
      vm.component.exposed.showToast(message, type, duration);
    };
    
  },
};
export default VueToast;

可以看到,该对象类型插件导出一个必须包含一个 install 函数的对象,该函数会在 app.use 安装插件时执行。接着,给 app 实例添加一个全局方法:$toast,该方法实现了以下四个功能:

1.创建了一个挂载容器 container

2.通过 createVNode 函数,将 ToastComponent 组件创建为虚拟节点(vm)。

3.通过 render 函数,将 vm 虚拟节点挂载到 container 容器上。

4.调用了 ToastComponent 组件暴露的 showToast 方法。

第二步: 创建 Toast 组件。

继续在plugins文件夹下新建Toast.vue 文件,用于定义 Toast 组件的模板和逻辑,代码如下所示:

代码语言:javascript复制
<template>
  <div :class="state.type" v-if="state.visible">{{ state.message }}</div>
</template>


<script setup>
import { reactive } from 'vue'
  
const state = reactive({
  message: '',
  type: '',
  visible: false,
})
// 1.显示 Toast 的方法
const showToast = (message, type, duration) => {
  state.message = message; // 显示的文本
  state.type = type; // 控制背景颜色
  state.visible = true; // 显示和隐藏
  setTimeout(() => {
    state.visible = false;
  }, duration);
}


// 2.将该方法暴露出去
defineExpose({
  showToast
})
</script>


<style scoped>
.vue-toast {
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  background-color: #333;
  color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}


.vue-toast.info {
  background-color: #3498db;
}


.vue-toast.success {
  background-color: #2ecc71;
}
</style>

可以看到,Toast 组件非常简单,主要是在界面上显示一个吐司布局,同时该组件还暴露了 showToast 方法来将 Toast 布局显示出来。

第三步: 安装Vue Toast插件。

修改 main.js 文件来安装该插件,代码如下所示(省略了样式):

代码语言:javascript复制
// main.js
import { createApp } from 'vue';
import App from './06_VueToast的使用/App.vue'


import VueToast from './plugins/vue-toast'; // 1.导入插件
const app = createApp(App);
app.use(VueToast); // 2.安装 Vue Toast 插件


app.mount('#app');

可以看到,这里先导入了 Vue Toast 插件,然后调用app.use函数来安装该插件。

第四步: 在 App 中使用该插件。

在01_learn_component项目的src目录下新建06_VueToast的使用文件夹,然后在该文件夹下新建App.vue组件。

App.vue组件,代码如下所示:

代码语言:javascript复制
<template>
  <div style="border:1px solid #ddd;margin:4px">
    App组件
    <button @click="showToast">显示 Toast</button>
  </div>
</template>
<script setup>
 import { getCurrentInstance } from "vue";
 const instance = getCurrentInstance();  // 1.拿到 this 实例
 const showToast = ()=>{
    instance.appContext.config.globalProperties  // 2.调用全局方法
        .$toast('这是一个示例 toast 消息', 'success');
}
</script>

可以看到,这里先调用 getCurrentInstance 函数拿到当前组件的实例,然后通过当前组件实例对象访问到全局的toast方法(即前面插件注册的全局方法),然后调用toast方法显示一个吐司(Toast)。

最后,修改 main.js 程序入口文件,将导入的 App.vue 组件改为06_VueToast的使用/App.vue路径下的App.vue组件。

保存代码,在浏览器中显示的效果如图所示。当单击“显示 Toast”按钮时,页面上会显示一个绿色吐司(Toast)。

以上内容节选自《Vue.js 3 TypeScript完全指南》一书。

发布:刘恩惠 审核:陈歆懿

0 人点赞