在 Vue3 項目中,我們經常會用到 ElNotification
作為消息提醒組件,尤其是在異步操作、任務完成或用戶需要交互確認時。然而,Element Plus 默認的 Notification
是非交互式的,不能直接嵌入按鈕或事件。
今天我們來實現一個帶自定義按鈕和點擊事件的 Notification 提示框,并且支持手動關閉。
? 目標效果
我們希望實現這樣的功能:
- 彈出一個固定的通知框(
duration: false
) - 內容中嵌入自定義按鈕
- 點擊按鈕后執行事件回調,并關閉該通知框
📦 技術棧
- Vue 3 Composition API
- Element Plus
- 渲染自定義內容:
h()
渲染函數 - 引用通知對象:
ref
+id
進行映射管理
? 實現方案
1. 基礎代碼結構
<script setup lang="ts">
import { ElNotification } from 'element-plus'
import { ref, h } from 'vue'// 存儲所有通知實例
const notify = ref<Record<string, any>>({})// 觸發通知
const fc = () => {const id = Math.random().toString()const closeNotification = () => {notify.value[id]?.close()delete notify.value[id]}notify.value[id] = ElNotification({type: 'warning',title: '提醒',duration: 0,dangerouslyUseHTMLString: true,message: h('div', [h('p', {}, '消息內容'),h('p',{style: 'width: 250px; display: flex; justify-content: space-between;',},[h('a',{style: 'color: #409EFF; cursor: pointer;',onClick: closeNotification,},'確定'),]),]),})
}
</script>
🔍 核心邏輯說明
關鍵點 | 說明 |
---|---|
notify.value | 存儲所有當前激活的通知框引用,方便后續關閉 |
Math.random().toString() | 用作唯一 key 區分多個通知(可換成 UUID) |
h() | Vue 的渲染函數,用于嵌入 HTML/組件內容 |
dangerouslyUseHTMLString: true | 與 h() 沖突,寫錯會無效;這里只是保留展示形式建議使用 h() 就不加它 |
duration: 0 | 通知不會自動關閉,用戶需點擊按鈕關閉 |
onClick: closeNotification | 點擊按鈕時關閉對應通知框 |
🧠 可擴展思路
-
多個按鈕場景
h('button', { onClick: handleReject }, '拒絕') h('button', { onClick: handleAccept }, '接受')
-
替換為組件
使用defineComponent
包一層小組件傳給message
-
支持通知唯一性
通知已存在就不再重復彈出,避免重復提醒 -
封裝為 composable
const useNotification = () => {const notifyMap = ref({})const show = (opts: { message: string; onClick: Fn }) => { ... }return { show } }
🧪 實際應用場景
- 后臺審批通知:“你有一條待處理任務”
- 導出提示:“導出任務正在生成,點擊查看”
- 會話提醒:“對話超時,點擊繼續會話”
🔚 小結
Element Plus 的 ElNotification
雖然是用于展示型通知,但通過 h()
渲染函數可以實現非常靈活的交互內容。借助 Vue3 的組合式 API,我們還能輕松實現批量通知管理、動態事件綁定,極大提升了用戶體驗與可維護性。