Antd Vue 组件提示功能二次封装
2026年1月27日 23:43
本次封装组件有用到「Message 全局提示」与「Notification 通知提醒框」
- 若只使用
Message:无法满足「重要通知需要持久化、需要用户手动关闭」的场景,重要信息可能被用户忽略(3 秒自动消失)。 - 若只使用
Notification:对于简单的快捷反馈,会显得过于笨重,高频次弹出会占用过多页面空间,影响用户操作,降低体验。
一、 前期准备:查阅 Antd 官方 API
- 进入 Ant Design Vue 官方文档,找到「Message 全局提示」与「Notification 通知提醒框」的 API 章节
- 两种组件均支持通过
xxx.config({})格式进行全局默认配置,文档中会列出所有可配置参数(如显示位置、停留时长等) - 核心需用到
message(轻量顶部提示)和notification(右下角通知框)两个组件,用于后续功能封装优化
![]()
二、 核心封装:实现统一提示工具(antd-message.js)
1. 导入依赖与全局默认配置
import { notification, message } from 'ant-design-vue';
import { messageContent } from './messageContent';
// 全局配置 notification(通知框)的默认行为
notification.config({
placement: 'bottomRight', // 通知框显示位置:右下角
bottom: '50px', // 距离底部 50px
duration: 3 // 默认停留 3 秒(自动关闭)
});
// 复制 message 实例到 messageCopy
// 目的是隔离原始实例,避免后续操作意外修改 message 原生属性,属于严谨编码习惯,也可直接使用 message
const messageCopy = message;
// 全局配置 messageCopy(即 message)的默认行为
messageCopy.config({
top: '150px', // 提示框距离顶部 150px(默认是顶部 8px)
duration: 3, // 默认停留 3 秒
maxCount: 5 // 最多同时显示 5 个提示框(避免多次点击弹出过多)
});
2. 封装统一提示方法(以 error 为例)
const messageConfig = {
error: (msg, type, config = {}) => {
// 1. 生成唯一 key,用于标识当前的 notification 实例,方便后续手动关闭
const key = `open${Date.now()}`;
// 2. 判断展示形式:根据传入的 type 是否为 'center',切换两种提示组件
if (type === 'center') {
// 情况 1:type === 'center' → 使用 messageCopy 的 error 方法(顶部轻量提示)
messageCopy.error(msg, config.duration, config.onClose);
} else {
// 情况 2:其他 type → 使用 notification 的 error 方法(右下角通知框)
notification.error({
class: 'notification-content', // 给通知框添加自定义 class,方便后续自定义样式
message: () => {
// 3. 统一渲染通知框内容:调用 messageContent 生成自定义模板
return messageContent({
msg, // 提示文本
isHtml: config.isHtml, // 是否支持 HTML 渲染(外部传入配置)
close: () => notification.close(key) // 手动关闭回调:关闭当前实例
});
},
key, // 传入唯一 key,关联当前 notification 实例
...config // 合并外部传入的 config,允许覆盖默认配置
});
}
}
// 可继续封装 success、warn、info 等方法,逻辑与 error 一致
};
3. 封装关键细节说明
- 接收外部传入的
config参数,默认值为{},支持覆盖duration(停留时长)、onClose(关闭回调)、isHtml(是否支持 HTML)等配置 - 使用
...config合并外部配置,可传入 Antdnotification支持的所有配置,优先级高于全局默认配置 - 手动关闭实现:通过
Date.now()生成唯一key,关联当前notification实例,配合messageContent传入的close回调,实现精准关闭当前通知框
三、 自定义内容渲染:messageContent 函数(JSX 语法)
1. 实现代码
import xssHtml from '../filter/xssHtml.js';
export function messageContent ({
msg,
close,
isHtml = true
}) {
return (<>
{isHtml ? <span v-html={xssHtml(msg)}></span> : msg}
<span class='notification-notice-close-btn icon-card_close' onClick={() => close()}></span>
</>);
}
2. 核心说明
- 使用
<>空片段包裹内容,避免生成额外 DOM 节点,同时满足 JSX 单根节点要求 - 条件渲染:
isHtml为true时,使用v-html渲染 HTML 内容;为false时,直接渲染纯文本 - 安全保障:
v-html={xssHtml(msg)}对 HTML 内容进行 XSS 过滤,防止恶意脚本攻击 - 自定义关闭按钮:绑定
onClick事件,调用传入的close回调,实现手动关闭通知框
四、 全局注册:Antd 组件与自定义提示工具
1. 导入所需组件与资源
// 第一部分:批量导入 antdv 常用基础组件(从核心包导入)
import {
Collapse, Tooltip, Pagination, Layout
} from 'ant-design-vue';
// 第二部分:单独导入需要依赖 moment.js 的时间相关组件(特殊处理)
import DatePicker from 'ant-design-vue/es/date-picker/moment';
import TimePicker from 'ant-design-vue/es/time-picker/moment';
import Calendar from 'ant-design-vue/es/calendar/moment';
// 第三部分:导入 antdv 全局样式重置文件(必选)
import 'ant-design-vue/dist/reset.css';
// 第四部分:导入封装好的自定义 message 工具
import message from './antd-message';
2. 导入细节说明
- 批量导入 vs 单独导入:基础组件(Button、Table 等)从核心包批量导入,时间相关组件从
es/xxx/moment单独导入,确保moment.js依赖正常加载,减少冗余打包 -
reset.css:Antd 4.x 及以上版本的全局样式文件,用于重置浏览器默认样式、统一组件样式,缺失会导致组件样式错乱 - 自定义
message:导入之前封装的messageConfig,后续全局挂载供全项目使用
3. 定义全局注册核心函数
// 定义接收 Vue 应用实例(app)的函数,用于注册组件
const useAntdComponent = (app) => {
// 第一步:通过 app.use() 逐个注册 antdv 组件(全局注册)
app.use(Collapse);
app.use(Tooltip);
app.use(Pagination);
app.use(Layout);
app.use(DatePicker);
app.use(TimePicker);
app.use(Calendar);
// 第二步:全局挂载自定义 message 到 Vue 实例的 globalProperties 上
app.config.globalProperties.$message = message;
};
4. 全局注册细节说明
-
app.use(组件):Antd 组件均暴露install方法,调用该方法将组件注册为全局组件,后续无需手动导入即可在模板中使用 -
app.config.globalProperties.$message = message:Vue 3 中挂载全局属性的方式,挂载后可在组件中通过this.$message(普通 script)或proxy.$message(script setup)访问
5. 导出注册函数与 message 工具
export default {
useAntdComponent,
message
};
6. 入口文件调用(main.js / main.ts)
import { createApp } from 'vue'
import App from './App.vue'
// 导入封装的 antdv 全局注册工具
import antdTools from './path/to/antd-component-register.js'
// 创建 Vue 应用实例
const app = createApp(App)
// 调用注册函数,完成组件全局注册和 message 全局挂载
antdTools.useAntdComponent(app)
// 挂载 App 到 DOM
app.mount('#app')
7. 调用后生效效果
- 所有注册的 Antd 组件可直接在模板中使用,无需手动导入
- 自定义
message工具可在全项目组件中访问,无需重复导入
五、 优化打包体积:配置 babel-plugin-import 插件
- 未配置该插件时,即使按需导入组件,打包也会包含整个 Antd 库,导致体积过大
- 配置后,只会打包使用到的组件代码,有效减小打包体积
- 配置示例(babel.config.js)
module.exports = {
plugins: [
[
'import',
{ libraryName: 'ant-design-vue', libraryDirectory: 'es', style: 'css' }
],
[
'import',
{ libraryName: 'vxe-table', style: true }, 'vxe-table'
],
'@vue/babel-plugin-jsx'
],
presets: [
'@vue/cli-plugin-babel/preset',
['@babel/preset-react', { runtime: 'classic' }]
]
};
六、 验证使用:全局组件与提示工具实战
<template>
<!-- 无需导入 Button,直接使用 <a-button> -->
<a-button type="primary" @click="showError">点击显示错误提示</a-button>
<!-- 无需导入 Table,直接使用 <a-table> -->
<a-table :columns="columns" :data-source="data" bordered />
</template>
<script setup>
import { getCurrentInstance } from 'vue'
// 获取 proxy,访问全局挂载的 $message
const { proxy } = getCurrentInstance()
// 调用全局挂载的 message 工具
const showError = () => {
proxy.$message.error('这是全局挂载后的错误提示', 'center')
}
// 表格测试数据
const columns = [
{ title: '姓名', dataIndex: 'name', key: 'name' },
{ title: '年龄', dataIndex: 'age', key: 'age' }
]
const data = [{ key: 1, name: '张三', age: 20 }]
</script>
总结
- 核心流程:查阅官方 API → 封装统一提示工具 → 自定义内容渲染(防 XSS)→ 全局注册组件与工具 → 配置打包优化插件 → 验证使用
- 关键亮点:实现两种提示组件的统一调用、支持配置覆盖、保障 HTML 渲染安全、减少重复导入工作、优化打包体积
- 最终效果:全项目可直接使用 Antd 常用组件和
$message提示工具,提升开发效率,保证代码统一性