Vue3 + Element Plus 全局 Message、Notification 封装与规范|Vue生态精选

前端实战:Vue3 + Element Plus 全局 Message、Notification 封装教程,从概念区分、场景选择到统一错误处理、代码落地,一站式学会前端提示框封装,告别混乱代码与重复开发。

📑 文章目录

  • 一、我们为什么要封装?
  • [二、概念扫盲:Message / Notification / Toast 有啥区别?](#二、概念扫盲:Message / Notification / Toast 有啥区别? "#part2")
  • 三、典型使用场景
  • 四、封装思路:三层结构
  • 五、统一风格:主题、样式、交互
    • [5.1 风格统一要管什么?](#5.1 风格统一要管什么? "#part5_1")
    • [5.2 示例:统一配置](#5.2 示例:统一配置 "#part5_2")
  • 六、统一错误处理:拦截、提示、降级
    • [6.1 核心思路](#6.1 核心思路 "#part6_1")
    • [6.2 错误码与文案映射示例](#6.2 错误码与文案映射示例 "#part6_2")
    • [6.3 在 axios 里用](#6.3 在 axios 里用 "#part6_3")
  • [七、完整封装示例(Vue 3 + Element Plus)](#七、完整封装示例(Vue 3 + Element Plus) "#part7")
    • [7.1 封装文件结构](#7.1 封装文件结构 "#part7_1")
    • [7.2 封装实现](#7.2 封装实现 "#part7_2")
    • [7.3 业务里怎么用](#7.3 业务里怎么用 "#part7_3")
    • [7.4 全局挂载(可选)](#7.4 全局挂载(可选) "#part7_4")
  • 八、常见坑点与排查思路
    • [8.1 同一个提示狂弹](#8.1 同一个提示狂弹 "#part8_1")
    • [8.2 样式跟项目不一致](#8.2 样式跟项目不一致 "#part8_2")
    • [8.3 错误提示内容太"技术"](#8.3 错误提示内容太“技术” "#part8_3")
    • [8.4 封装后换 UI 库很痛苦](#8.4 封装后换 UI 库很痛苦 "#part8_4")
    • [8.5 在 setup 里没有 this](#8.5 在 setup 里没有 this "#part8_5")
  • 九、实战规范总结
  • 十、小结

同学们好,我是 Eugene(尤金),一个拥有多年中后台开发经验的前端工程师~

(Eugene 发音很简单,/juːˈdʒiːn/,大家怎么顺口怎么叫就好)

你是否也有过:明明学过很多技术,一到关键时候却讲不出来、甚至写不出来?

你是否也曾怀疑自己,是不是太笨了,明明感觉会,却总差一口气?

就算想沉下心从头梳理,可工作那么忙,回家还要陪伴家人。

一天只有24小时,时间永远不够用,常常感到力不从心。

技术行业,本就是逆水行舟,不进则退。

如果你也有同样的困扰,别慌。

从现在开始,跟着我一起心态归零 ,利用碎片时间,来一次彻彻底底的基础扫盲

这一次,我们一起慢慢来,扎扎实实变强。

不搞花里胡哨的理论堆砌,只分享看得懂、用得上的前端干货,

咱们一起稳步积累,真正摆脱"面向搜索引擎写代码"的尴尬。

一、我们为什么要封装?

很多同学会直接这样写:

javascript 复制代码
// 散落在业务里的各种提示
this.$message.success('保存成功')
ElMessage.error('网络错误')
alert('操作失败')  // 甚至还有人用 alert

看起来能用,但会带来这些问题:

  • 提示风格不统一:有的用 Message,有的用 Notification,有的用 alert
  • 错误处理分散:每个接口各自 try-catch 各自 message
  • 难以维护:改文案、改样式、加埋点,要改很多地方
  • 用户体验差:错误提示不统一,成功/失败没规范

所以需要:把通知和消息系统统一封装,集中管理风格和错误处理

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

二、概念扫盲:Message / Notification / Toast 有啥区别?

类型 特点 典型场景
Message 轻量、短暂、通常居中或顶部,自动消失 操作结果反馈:保存成功、删除成功
Notification 带标题、正文,可带操作按钮,位置可配置 系统通知、任务完成、重要提示
Toast 和 Message 概念接近,有些库叫 Toast 同上,多用于移动端

可以简单记:Message 偏轻量,Notification 偏正式、信息更多。封装时建议:

  • 简单反馈 → Message
  • 需要标题、描述、操作 → Notification

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

三、典型使用场景

  1. 接口成功/失败:统一用 Message,成功/警告/错误三种类型
  2. 表单校验失败:一般用 Message,文案来自校验规则
  3. 全局错误:如 401、403、500 → 统一错误处理 + Message/Notification
  4. 长时间任务完成:如导出、报表生成 → 用 Notification 更合适
  5. 业务重要事件:如订单状态变更 → Notification + 操作入口

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

四、封装思路:三层结构

scss 复制代码
┌─────────────────────────────────────┐
│  业务层:直接调用 msg.success() 等  
├─────────────────────────────────────┤
│  封装层:msg / notify 统一入口      
│  - 统一风格                       
│  - 统一文案模板                   
│  - 统一埋点/日志                 
├─────────────────────────────────────┤
│  底层:Element Plus / Ant Design 等
└─────────────────────────────────────┘

业务层只调用封装好的 API,不直接接触 UI 库。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

五、统一风格:主题、样式、交互

5.1 风格统一要管什么?

  • 类型:success / warning / error / info
  • 位置:如 Message 顶部居中,Notification 右上角
  • 持续时间:成功 2s,错误 4s 等
  • 样式:颜色、圆角、阴影等
  • 防重复:相同文案不重复弹

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

5.2 示例:统一配置

javascript 复制代码
// src/utils/message.config.js

/**
 * Message 统一配置
 * 所有地方用 Message 时都走这套配置,保证风格一致
 */
export const MESSAGE_CONFIG = {
  duration: 2000,           // 默认 2 秒消失
  showClose: false,         // 不显示关闭按钮,靠自动消失
  center: true,             // 水平居中
  offset: 80,               // 距离顶部的距离
  grouping: true,           // 相同内容合并显示,避免刷屏
}

/**
 * 不同类型建议的 duration
 * 成功可以短一点,错误要留足阅读时间
 */
export const DURATION_BY_TYPE = {
  success: 2000,
  warning: 3000,
  error: 4000,
  info: 2500,
}

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

六、统一错误处理:拦截、提示、降级

6.1 核心思路

  • HTTP 拦截器:统一捕获 401、403、500 等
  • 业务错误码映射:后端错误码 → 前端文案
  • 兜底:网络异常、超时等给出通用提示

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

6.2 错误码与文案映射示例

javascript 复制代码
// src/utils/errorCodeMap.js

/**
 * 后端错误码 → 前端展示文案
 * 避免把后端原始错误直接抛给用户
 */
export const ERROR_CODE_MAP = {
  401: '登录已过期,请重新登录',
  403: '没有权限执行此操作',
  404: '请求的资源不存在',
  500: '服务器异常,请稍后重试',
  10001: '参数错误',
  10002: '数据已存在',
  // ... 按你们项目补充
}

/**
 * 根据错误码获取友好提示
 */
export function getErrorMessage(code, defaultMsg = '操作失败,请稍后重试') {
  return ERROR_CODE_MAP[code] || defaultMsg
}

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

6.3 在 axios 里用

javascript 复制代码
// src/api/request.js 示意

import axios from 'axios'
import { ElMessage } from 'element-plus'
import { getErrorMessage } from '@/utils/errorCodeMap'

const request = axios.create({
  baseURL: '/api',
  timeout: 10000,
})

// 响应拦截器:统一错误处理
request.interceptors.response.use(
  (response) => {
    const { code, data, message } = response.data
    // 假设业务成功是 code === 0
    if (code !== 0) {
      ElMessage.error(getErrorMessage(code, message))
      return Promise.reject(new Error(message))
    }
    return data
  },
  (error) => {
    if (error.response) {
      const { status } = error.response
      const msg = getErrorMessage(status)
      ElMessage.error(msg)
      // 401 可以在这里跳转登录
      if (status === 401) {
        // router.push('/login')
      }
    } else {
      ElMessage.error('网络异常,请检查网络后重试')
    }
    return Promise.reject(error)
  }
)

export default request

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

七、完整封装示例(Vue 3 + Element Plus)

7.1 封装文件结构

bash 复制代码
src/
├── utils/
│   ├── message.config.js    # 配置
│   ├── errorCodeMap.js      # 错误码映射
│   └── message.js           # 封装入口

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

7.2 封装实现

javascript 复制代码
// src/utils/message.js

import { ElMessage, ElNotification } from 'element-plus'
import { MESSAGE_CONFIG, DURATION_BY_TYPE } from './message.config'
import { getErrorMessage } from './errorCodeMap'

/**
 * 全局 Message 封装
 * 统一风格、统一入口,方便以后替换 UI 库或加埋点
 */

function createMessage(type) {
  return (content, duration) => {
    ElMessage({
      ...MESSAGE_CONFIG,
      type,
      message: typeof content === 'string' ? content : content?.message || '操作成功',
      duration: duration ?? DURATION_BY_TYPE[type] ?? MESSAGE_CONFIG.duration,
    })
  }
}

// 对外暴露的 API
export const msg = {
  success: createMessage('success'),
  warning: createMessage('warning'),
  error: createMessage('error'),
  info: createMessage('info'),
}

/**
 * 全局 Notification 封装
 * 适合需要标题、描述、操作按钮的场景
 */
export const notify = {
  success(title, message, options = {}) {
    ElNotification({
      type: 'success',
      title: title || '成功',
      message: message || '',
      duration: 4000,
      position: 'top-right',
      ...options,
    })
  },
  error(title, message, options = {}) {
    ElNotification({
      type: 'error',
      title: title || '错误',
      message: message || '',
      duration: 5000,
      position: 'top-right',
      ...options,
    })
  },
  // warning、info 同理...
}

/**
 * 统一错误提示入口
 * 支持:错误码、Error 对象、字符串
 */
export function showError(error) {
  let message = '操作失败,请稍后重试'
  if (typeof error === 'number') {
    message = getErrorMessage(error)
  } else if (error?.message) {
    message = error.message
  } else if (typeof error === 'string') {
    message = error
  }
  msg.error(message)
}

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

7.3 业务里怎么用

javascript 复制代码
// 业务组件里
import { msg, notify, showError } from '@/utils/message'

// 简单成功反馈
msg.success('保存成功')

// 接口失败时(如果拦截器没处理,可以手动调)
try {
  await saveData()
  msg.success('保存成功')
} catch (e) {
  showError(e)
}

// 重要通知
notify.success('导出完成', '您的报表已生成,请到下载中心查看')

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

7.4 全局挂载(可选)

javascript 复制代码
// main.js
import { msg, notify, showError } from '@/utils/message'

app.config.globalProperties.$msg = msg
app.config.globalProperties.$notify = notify
app.config.globalProperties.$showError = showError

// 组件内:this.$msg.success('保存成功')

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

八、常见坑点与排查思路

8.1 同一个提示狂弹

  • 原因:接口失败在循环/频繁请求里被多次触发。
  • 做法 :开启 grouping,或在封装层做「相同文案节流」。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

8.2 样式跟项目不一致

  • 原因:直接用了 UI 库默认主题,或部分地方用内联样式覆盖。
  • 做法:所有 Message/Notification 都走封装层,在封装里统一传入配置,必要时用 CSS 变量或主题覆盖。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

8.3 错误提示内容太"技术"

  • 原因 :直接把后端 messageError 文本展示给用户。
  • 做法:用错误码映射表,把技术信息转成用户可读文案。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

8.4 封装后换 UI 库很痛苦

  • 原因 :业务里到处直接调用 ElMessageElNotification
  • 做法 :业务只依赖 msgnotify,底层实现集中在 message.js,换库只改这一层。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

8.5 在 setup 里没有 this

  • 做法 :用 import { msg } from '@/utils/message' 直接引入,不依赖 this.$msg

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

九、实战规范总结

规范 说明
统一入口 只用 msg / notify,不直接调用 UI 库
统一风格 通过 message.config.js 统一 duration、位置、样式
统一错误处理 用错误码映射 + axios 拦截器,业务少写 try-catch
类型区分 简单反馈用 Message,复杂通知用 Notification
文案友好 错误码转成用户能看懂的话,不暴露技术细节
可扩展 封装层预留埋点、日志、国际化等扩展点

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")

十、小结

封装全局 Message / Notification 的核心是:

  1. 统一入口 :所有提示都从 msg / notify 走。
  2. 统一风格:配置集中管理,避免到处写死。
  3. 统一错误处理:拦截器 + 错误码映射,减少重复代码。
  4. 把用户当小白:错误文案要易懂,不吓人。

[⬆ 返回目录](#⬆ 返回目录 "#catalogue")


学习本就是一场持久战,不需要急着一口吃成胖子。哪怕今天你只记住了一点点,这都是实打实的进步。

后续我还会继续用这种大白话、讲实战方式,带大家扫盲更多前端基础。

关注我,不迷路,咱们把那些曾经模糊的知识点,一个个彻底搞清楚。

如果你觉得这篇内容对你有帮助,不妨点赞+收藏,下次写代码卡壳时,拿出来翻一翻,比搜引擎更靠谱。

我是 Eugene,你的电子学友,我们下一篇干货见~

相关推荐
掘金安东尼1 小时前
活动落地页效率翻倍:RollCode 这次更新有点猛
前端·低代码·面试
北冥有鱼其名为坤1 小时前
诡异!vite+vue3 项目图片无法显示,我怀疑人生…
前端
FE_winter2 小时前
OpenClaw Skills 进阶实战:前端开发者的 AI 技能库搭建指南
前端·后端·程序员
wordbaby2 小时前
小白也能看懂:小程序 Canvas 给图片添加水印的终极指南
前端·canvas
Mapmost2 小时前
“汛”速响应:流域洪水仿真分析,如何实现淹没过程的精准推演?
前端
梁大虎2 小时前
Electrobun 开发必看:CEF 依赖下载失败?手动解压一招搞定!
前端·javascript·后端
青青家的小灰灰2 小时前
拒绝 Prop Drilling 与隐式耦合:Vue 组件通讯的全景指南与最佳实践
前端·javascript·vue.js
代码老中医2 小时前
我赌5年后,90%的CRUD页面都是AI生成的
前端
bluceli2 小时前
前端监控与错误追踪实战指南:构建稳定应用的终极方案
前端·监控