重生之我在学Vue–第16天 Vue 3 插件开发
文章目录
- 重生之我在学Vue--第16天 Vue 3 插件开发
- 前言
- 一、插件的作用与开发思路
- 1.1 插件能做什么?
- 1.2 插件开发四部曲
- 二、开发全局通知插件
- 2.1 插件基础结构
- 2.2 完整插件代码(带注释解析)
- 2.3 样式文件 notification.css
- 三、插件的安装与使用
- 3.1 在 main.js 中安装
- 3.2 在组件中使用
- 四、插件开发进阶技巧
- 4.1 支持 TypeScript 类型
- 4.2 响应式状态管理
- 五、今日任务:开发并集成通知插件
- 任务要求
- 代码示例:动画实现
- 结语
前言
在 Vue 的世界里,插件就像是一把万能钥匙,它能让我们将通用功能封装成可复用的模块,实现 全局能力扩展。今天我们将从零开发一个全局通知插件,让你的 Vue 应用拥有优雅的消息提示能力!
Vue3 官方中文文档传送点: 插件 | Vue.js
插件开发的核心是理解 install 方法 和 全局资源注册 的机制
Vue前端成仙之路:Vue 前端成仙之路_野生的程序媛的博客-CSDN博客
GO后端成神之路:Go 后端成神之路_野生的程序媛的博客-CSDN博客
一、插件的作用与开发思路
1.1 插件能做什么?
场景 | 实现方式 | 典型案例 |
---|---|---|
全局组件注册 | app.component() | Element Plus 组件库 |
全局指令添加 | app.directive() | v-loading 指令 |
全局混入逻辑 | app.mixin() | 权限校验逻辑 |
全局属性/方法注入 | app.config.globalProperties | $axios 实例 |
1.2 插件开发四部曲
- 定义插件对象:包含 install 方法
- 注册全局资源:组件/指令/属性等
- 注入应用实例:通过 app.use() 安装
- 项目中调用:任意组件内使用
二、开发全局通知插件
2.1 插件基础结构
// plugins/notification.js
export default {
install: (app, options) => {
// 在这里注册全局资源
}
}
2.2 完整插件代码(带注释解析)
import { h, render, ref } from 'vue'
// 1. 创建通知容器组件
const NotificationContainer = {
setup() {
const notifications = ref([])
// 添加通知
const add = (notification) => {
notifications.value.push(notification)
// 自动关闭
if (notification.duration > 0) {
setTimeout(() => {
remove(notification.id)
}, notification.duration)
}
}
// 移除通知
const remove = (id) => {
notifications.value = notifications.value.filter(n => n.id !== id)
}
return { notifications, add, remove }
},
render() {
return h('div', { class: 'notification-container' },
this.notifications.map(notification =>
h(NotificationItem, {
key: notification.id,
...notification,
onClose: () => this.remove(notification.id)
})
)
)
}
}
// 2. 单个通知项组件
const NotificationItem = {
props: ['type', 'message', 'onClose'],
render() {
return h('div', { class: ['notification', this.type] }, [
h('span', this.message),
h('button', { onClick: this.onClose }, '×')
])
}
}
// 3. 插件安装逻辑
export default {
install(app) {
// 创建挂载节点
const mountNode = document.createElement('div')
document.body.appendChild(mountNode)
// 渲染通知容器
render(h(NotificationContainer), mountNode)
// 注入全局方法
app.config.globalProperties.$notify = {
show: (message, options = {}) => {
const id = Date.now()
const notification = {
id,
message,
type: options.type || 'info',
duration: options.duration || 3000
}
// 通过事件总线触发添加
const event = new CustomEvent('add-notification', { detail: notification })
document.dispatchEvent(event)
}
}
// 监听添加事件
document.addEventListener('add-notification', (e) => {
const instance = mountNode._vnode.component.ctx
instance.add(e.detail)
})
}
}
2.3 样式文件 notification.css
.notification-container {
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
}
.notification {
padding: 12px 20px;
margin-bottom: 10px;
border-radius: 4px;
background: #f4f4f5;
color: #909399;
min-width: 200px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 12px rgba(0,0,0,.1);
}
.notification.success {
background: #f0f9eb;
color: #67c23a;
}
.notification.error {
background: #fef0f0;
color: #f56c6c;
}
三、插件的安装与使用
3.1 在 main.js 中安装
import { createApp } from 'vue'
import App from './App.vue'
import notification from './plugins/notification'
import './styles/notification.css'
const app = createApp(App)
app.use(notification)
app.mount('#app')
3.2 在组件中使用
<template>
<button @click="showNotification">触发通知</button>
</template>
<script setup>
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const showNotification = () => {
proxy.$notify.show('操作成功!', {
type: 'success',
duration: 2000
})
}
</script>
四、插件开发进阶技巧
4.1 支持 TypeScript 类型
// types/notification.d.ts
import { ComponentPublicInstance } from 'vue'
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$notify: {
show: (message: string, options?: NotificationOptions) => void
}
}
}
interface NotificationOptions {
type?: 'info' | 'success' | 'error'
duration?: number
}
4.2 响应式状态管理
// 使用 Pinia 管理通知状态
import { defineStore } from 'pinia'
export const useNotificationStore = defineStore('notification', {
state: () => ({
list: []
}),
actions: {
add(notification) {
this.list.push(notification)
},
remove(id) {
this.list = this.list.filter(n => n.id !== id)
}
}
})
五、今日任务:开发并集成通知插件
任务要求
- 按照示例代码实现通知插件
- 在任务管理系统中添加以下通知场景:
• 任务创建成功
• 任务删除确认提示
• 网络请求失败的报错提示 - (扩展)实现通知的渐入渐出动画
代码示例:动画实现
<template>
<TransitionGroup
name="notification"
tag="div"
class="notification-container"
>
<!-- 通知项 -->
</TransitionGroup>
</template>
<style>
.notification-enter-active,
.notification-leave-active {
transition: all 0.5s ease;
}
.notification-enter-from,
.notification-leave-to {
opacity: 0;
transform: translateX(100%);
}
</style>
结语
通过开发全局通知插件,我们掌握了 Vue 插件开发的 核心模式:利用 install 方法扩展全局能力。插件开发的关键点在于:
- 全局资源隔离:通过 DOM 操作创建独立挂载点
- 响应式状态管理:使用 ref/reactive 跟踪通知状态
- 架构可扩展性:支持类型扩展、样式定制等功能