普通视图

发现新文章,点击刷新页面。
今天 — 2026年1月28日首页

Antd Vue 组件提示功能二次封装

作者 yyt_
2026年1月27日 23:43

本次封装组件有用到「Message 全局提示」与「Notification 通知提醒框」

  • 若只使用 Message:无法满足「重要通知需要持久化、需要用户手动关闭」的场景,重要信息可能被用户忽略(3 秒自动消失)。
  • 若只使用 Notification:对于简单的快捷反馈,会显得过于笨重,高频次弹出会占用过多页面空间,影响用户操作,降低体验。

一、 前期准备:查阅 Antd 官方 API

  1. 进入 Ant Design Vue 官方文档,找到「Message 全局提示」与「Notification 通知提醒框」的 API 章节
  2. 两种组件均支持通过 xxx.config({}) 格式进行全局默认配置,文档中会列出所有可配置参数(如显示位置、停留时长等)
  3. 核心需用到 message(轻量顶部提示)和 notification(右下角通知框)两个组件,用于后续功能封装优化

image.png

二、 核心封装:实现统一提示工具(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. 封装关键细节说明

  1. 接收外部传入的 config 参数,默认值为 {},支持覆盖 duration(停留时长)、onClose(关闭回调)、isHtml(是否支持 HTML)等配置
  2. 使用 ...config 合并外部配置,可传入 Antd notification 支持的所有配置,优先级高于全局默认配置
  3. 手动关闭实现:通过 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. 核心说明

  1. 使用 <> 空片段包裹内容,避免生成额外 DOM 节点,同时满足 JSX 单根节点要求
  2. 条件渲染:isHtmltrue 时,使用 v-html 渲染 HTML 内容;为 false 时,直接渲染纯文本
  3. 安全保障:v-html={xssHtml(msg)} 对 HTML 内容进行 XSS 过滤,防止恶意脚本攻击
  4. 自定义关闭按钮:绑定 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. 导入细节说明

  1. 批量导入 vs 单独导入:基础组件(Button、Table 等)从核心包批量导入,时间相关组件从 es/xxx/moment 单独导入,确保 moment.js 依赖正常加载,减少冗余打包
  2. reset.css:Antd 4.x 及以上版本的全局样式文件,用于重置浏览器默认样式、统一组件样式,缺失会导致组件样式错乱
  3. 自定义 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. 全局注册细节说明

  1. app.use(组件):Antd 组件均暴露 install 方法,调用该方法将组件注册为全局组件,后续无需手动导入即可在模板中使用
  2. 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. 调用后生效效果

  1. 所有注册的 Antd 组件可直接在模板中使用,无需手动导入
  2. 自定义 message 工具可在全项目组件中访问,无需重复导入

五、 优化打包体积:配置 babel-plugin-import 插件

  1. 未配置该插件时,即使按需导入组件,打包也会包含整个 Antd 库,导致体积过大
  2. 配置后,只会打包使用到的组件代码,有效减小打包体积
  3. 配置示例(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>

总结

  1. 核心流程:查阅官方 API → 封装统一提示工具 → 自定义内容渲染(防 XSS)→ 全局注册组件与工具 → 配置打包优化插件 → 验证使用
  2. 关键亮点:实现两种提示组件的统一调用、支持配置覆盖、保障 HTML 渲染安全、减少重复导入工作、优化打包体积
  3. 最终效果:全项目可直接使用 Antd 常用组件和 $message 提示工具,提升开发效率,保证代码统一性
❌
❌