五分鐘一百行代碼,手寫一個vue項目全局通用的toast提示組件
前言:
我們已經分享過如何快速實現自己需要的全局彈框組件;
在開發 Vue 項目時,特別是H5頁面的項目,還有一個組件是我們非常常用的,它相對彈框來說沒有那么大,并且不需要手動關閉在需要更簡潔的提示用戶一些信息時非常常用,它就是 toast 提示組件;
接下來我們會帶著大家手寫一個全局的 toast 提示組件,當你在項目任何地方需要使用時,都可直接調用。
查看往期文章:
第一步:新建文件夾及主要文件
Vue項目中,一般來說我們公用組件是放在 src/components,所以我們直接在src/components/toast下新建如下兩個文件:
- index.vue:該文件是
toast組件的內容,跟我們寫普通 vue 組件一樣,包含toast的結構、樣式以及基礎邏輯; - index.js:注冊
index.vue組件為全局組件。因為該組件我們不需要手動關閉,并且涉及到添加元素和自動刪除元素,所以該文件會有一些元素層面上的操作和邏輯,相對上期的彈框組件的index.js的文件來說會相對復雜些,我們下邊會逐行講解,當然也會提供完整代碼,請往下看。
第二步:書寫組件內容
index.vue組件內容如下:
- 結構 + js 代碼
<template>
<transition name="appear">
<section class="toast" v-if="show">
<div v-html="msg" class="toast-con"></div>
</section>
</transition>
</template>
<script type="text/ecmascript-6">
export default {
name: "toast",
data() {
return {
show: false,
msg: '',
time: 1000
}
},
methods: {
async open() {
if (this.show) {
return;
}
this.show = true;
let result = await this.close();
return result;
},
close() {
return new Promise((resolve) => {
setTimeout(() => {
this.show = false;
resolve(true);
}, this.time);
});
}
}
}
</script>
代碼說明:
- 我們這里用到了
Vue的transition組件,用于包裹需要動畫效果的元素。name="appear" 指定了使用名為 "appear" 的過渡效果; <div v-html="msg" class="toast-con"></div>這句代碼是我們toast的主要內容,通過v-html + msg來動態屬性來插入,msg在index.js 中修改;- methods:定義組件的方法。
- open():異步方法,用于顯示 Toast。如果已顯示,則直接返回;否則設置 show 為 true 并調用 close() 方法等待其完成。
- close():返回一個 Promise,該 Promise 在 time 毫秒后解決,同時將 show 設置為 false,從而隱藏 Toast。
- 樣式
<style lang="less" scoped>
.default-message {
position: fixed;
right: 0;
top: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
background: rgba(0, 0, 0, 0.7);
.default-message-title {
color: #333;
margin: 0;
line-height: 1.5;
font-size: 18px;
min-height: 18px;
padding-top: 20px;
text-overflow: ellipsis;
font-weight: bold;
cursor: move;
text-align: center;
}
.default-message-content {
width: 85%;
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
background-color: #fff;
border-radius: 6px;
transition: all 0.2s ease-in;
color: #999;
font-size: 18px;
}
.default-message-value {
padding: 28px 18px;
text-align: center;
position: relative;
color: #999;
text-align: center;
font-size: 14px;
color: rgba(102, 102, 102, 1);
}
.default-message-btns {
// border-top: 1px solid #ddd;
display: flex;
height: 60px;
position: relative;
&:after {
position: absolute;
content: "";
display: inline-block;
left: 0;
right: 0;
top: 0;
height: 1px;
transform: scaleY(0.5);
background: #ddd;
}
.default-message-btn {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
padding: 0 3px;
}
.default-message-submit {
color: #26a2ff;
}
.default-message-cancle {
color: #999;
position: relative;
&:after {
position: absolute;
content: "";
display: inline-block;
top: 0;
right: 0;
bottom: 0;
width: 1px;
transform: scaleX(0.5);
background: #ddd;
}
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
</style>
第三步:注冊成全局組件
import { createApp } from 'vue';
import ToastComponents from './index.vue';
const LayerToastId = 'layer-Toast-wrapper';
let Toast = async function (msg, time) {
time = time || 2000;
let ToastEl = document.getElementById(LayerToastId);
// 如果DOM中含有這個元素 不執行
if (ToastEl) {
return;
}
const div = document.createElement('div');
div.setAttribute('id', LayerToastId)
document.body.appendChild(div);
let layerToastEl = createApp(ToastComponents).mount('#' + LayerToastId);
// 修改組件中的data的值
layerToastEl.msg = msg;
layerToastEl.time = time;
// 執行組件中的方法 等待關閉后返回promise
let hasClosed = await layerToastEl.open();
// 當Toast提示關閉后再刪除外層元素 時間最好與css動畫一致
if (hasClosed) {
setTimeout(() => {
document.body.removeChild(div);
}, 400);
}
};
export default {
install (app) {
// 通過this.$toast訪問
app.config.globalProperties.$toast = Toast;
}
}
到這里,我們的彈框組件就完成了。下邊我們對一些比較重要的代碼做個解釋:
-
let Toast = async function這里表示Toast消息,我們把它注冊成一個異步函數,因為內部需要使用到定時器控制定時移除消息容器; -
let layerToastEl = createApp(ToastComponents).mount('#' + LayerToastId);- 這句代碼的意思是:把我們引入的
index.vue文件創建成一個 Vue 的應用實例,并掛載到新創建的 div 上。
- 這句代碼的意思是:把我們引入的
-
以下是
index.js文件的逐行解釋:
// 引入 Vue 的 createApp 函數,用于創建 Vue 應用實例
import { createApp } from 'vue';
// 引入 Toast 組件
import ToastComponents from './index.vue';
// 定義一個常量,用于存儲 Toast 組件的容器元素的 ID
const LayerToastId = 'layer-Toast-wrapper';
// 定義一個異步函數 Toast,用于顯示 Toast 消息
let Toast = async function (msg, time) {
// 如果未指定顯示時間,默認為 2000 毫秒
time = time || 2000;
// 獲取頁面上是否已存在 Toast 容器元素
let ToastEl = document.getElementById(LayerToastId);
// 如果已存在,不執行后續代碼,直接返回
if (ToastEl) {
return;
}
// 創建一個 div 元素,用作 Toast 組件的容器
const div = document.createElement('div');
// 為該 div 設置 ID
div.setAttribute('id', LayerToastId)
// 將創建的 div 添加到 body 中
document.body.appendChild(div);
// 創建一個 Vue 應用實例,并掛載到新創建的 div 上
let layerToastEl = createApp(ToastComponents).mount('#' + LayerToastId);
// 設置 Toast 組件的消息內容和顯示時間
layerToastEl.msg = msg;
layerToastEl.time = time;
// 調用 Toast 組件的 open 方法,顯示 Toast 并等待其關閉
let hasClosed = await layerToastEl.open();
// 當 Toast 關閉后,延遲 400 毫秒后移除 Toast 容器元素
// 這里的 400 毫秒延時可以與 CSS 動畫的時間相匹配,確保動畫播放完成
if (hasClosed) {
setTimeout(() => {
document.body.removeChild(div);
}, 400);
}
};
// 導出一個對象,包含 install 方法,用于在 Vue 應用中安裝這個 Toast 功能
export default {
install (app) {
// 將 Toast 函數添加到 Vue 應用的全局屬性中,使其可以通過 this.$toast 在任何組件中訪問
app.config.globalProperties.$toast = Toast;
}
}
項目中使用彈框
使用就非常簡單便利了,主要有以下幾種用法:
- Vue2 中使用:
// Vue2 中簡單使用
this.$toast("Toast提示在Vue2項目中的簡單使用"));
// Vue2中需要在提示后有進一步操作:可以任何你想的邏輯,包括發接口、頁面處理等。
await this.$toast("Toast提示在Vue2項目中使用后有后續邏輯", 3000);
handleFunction(); // 這里的函數代表提示后的邏輯代碼
- Vue3 中使用:
// 在 Vue3 中使用時需要先引入app
import { app } from "@/main";
// Vue3 中簡單使用
app.config.globalProperties.$toast("Toast提示在Vue3項目中的簡單使用", 3000);
// Vue2中需要在提示后有進一步操作:可以任何你想的邏輯,包括發接口、頁面處理等。
app.config.globalProperties.$toast("Toast提示在Vue3項目中使用后有后續邏輯");
handleFunction(); // 這里的函數代表提示后的邏輯代碼
說明:
- 我們可以在使用時傳入合適的顯示停留時間,如果為傳入,則按默認的 2000 毫秒顯示;
- 在 Vue3 中,你也可以把
$toast重新保存一下,后續不用每次都寫很長的app.config....
import { app } from "@/main";
const toast = app.config.globalProperties.$toast
toast("簡便地使用toast提示");
toast 圖片示例

說明:在停留 2000 毫秒(或者我們設置的停留時間)之后會自動關閉。
寫在后面
這是一個比較基礎和通用的黑色半透明提示消息,這邊示例的代碼是比較全的,對細節要求不大的小伙伴可以直接抄作業;
背景顏色、字體、布局等這些細節,因為每個業務場景不同,大家可以根據自己的需要適當調整;
通過修改結構和樣式代碼,你可以讓消息的樣式變得更加豐富或者更符合你的業務需求;
消息組件我們一樣是使用固定單位的,如果小伙伴的項目需要使用響應式大小,直接對應替換大小單位(rem、vw)即可;
對你有幫助的話給作者點點關注吧,你的支持是我不斷更新的動力!Peace and love~~

開發 Vue 項目時,特別是H5頁面,還有一個組件是我們非常常用的,它相對彈框沒有那么大,并且不需要手動關閉,在需要更簡潔的提示用戶一些信息時非常常用,它就是 `toast` 提示組件。
浙公網安備 33010602011771號