一起來做一下Vue全局提示組件
全局提示組件在前端中算是比較重要的,在開發(fā)業(yè)務時候肯定能用的上,畢竟任何報錯只要提示“服務器異常”就可以完美把鍋扔給后臺(手動滑稽)
全局提示組件在人氣比較??的 UI 組件庫必有他身影,可能叫法不太相同,有叫 message、toast、alert 等,但就是這么一玩意。

拿 ant-design-vue 組件庫為例

其核心代碼
message.info('This is a normal message')他是API的方式進行調用組件,以平常使用components注冊組件,之后在template中使用的方式不太相同
想要實現這個,其實并不困難
但在之前我想聲明一下:ant-design-vue 的 message 做個type分類,有info、success、error等。但為了讀者方便理解,我們統一就用message來進行調用,讀者可以根據本文提供的demo源碼自行進行調整(貼一下 ant-design-vue 源碼)

首先,我們在 components 目錄下創(chuàng)建 message 目錄,同時創(chuàng)建 Message.vue 和 index.js 文件

然后在 Message.vue 中寫
<!-- Message.vue -->
<template>
<div>{{ content }}</div>
</template>
<script>
export default {
name: 'Message',
props: {
content: {
type: String,
default: ''
}
}
}
</script>再者在 index.js 中寫
// index.js
import { render, createVNode } from 'vue'
import Message from './Message.vue'
export default function message (content) {
const div = document.createElement('div')
const vm = createVNode(Message, {
content
})
render(vm, div)
document.body.appendChild(div)
}最后在 app.vue 引入使用
<!-- app.vue -->
<template>
</template>
<script>
import message from './components/message'
export default{
setup() {
message('消息組件1')
message('消息組件2')
}
}
</script>效果:

ok,這樣就實現了以API的方式進行調用組件
其核心代碼其實只有以下
const div = document.createElement('div')
const vm = createVNode(Message, {
content
})
render(vm, div)
document.body.appendChild(div)createVNode 可以認為就是h函數,支持直接轉成虛擬dom對象

再去調用 render,渲染至div下,再將div插入body中
由于我們做的是全局組件,應該不被任何因素干擾,比如 vue-router
但是上面例子我們會發(fā)現,我們只要調用一個 message 方法,就要創(chuàng)建一個div插入至body,這顯然不是符合vue數據驅動視圖的理念

那,接下里進行改造
先從 Message.vue 文件開始
我們先定義一個消息列表messages,之后提供添加 add 和刪除delete消息列兩方法,再暴露add方法出去
當然,刪除消息是需要根據id進行刪除,可不能瞎刪
<!-- Message.vue -->
<script>
import { ref, unref } from 'vue'
export default {
name: 'Message',
setup (props, { expose }) {
// 消息列表
const messages = ref([])
let id = 0
// 生成id
const uuid = () => `message_${id++}`
// 添加消息對象
const add = (message) => {
const id = uuid()
const _message = {
...message,
id
}
unref(messages).push(_message)
const { duration = 3 } = message
// 設置定時器
const timer = setTimeout(() => {
clearTimeout(timer)
remove(id)
}, duration * 1000)
}
// 根據 id 刪除消息對象
const remove = (id) => {
messages.value = unref(messages).filter(message => message.id !== id)
}
// 暴露出add 和 remove
expose({
add
})
return {
messages
}
}
}
</script>用v-for把消息列表渲染出來,同時使用transition-group做一些列表過渡動畫
<!-- Message.vue -->
<template>
<transition-group
class="message"
tag="div"
>
<div
class="message-content"
v-for="message in messages"
:key="message.id"
>
{{ message.content }}
</div>
</transition-group>
</template>再編寫一點消息列表樣式和其彈出動畫樣式
<!-- Message.vue -->
<style scoped>
.message {
position: fixed;
z-index: 999;
top: 10px;
left: 50%;
transform: translateX(-50%);
}
.message-content {
padding: 8px 16px;
border-radius: 3px;
box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
background: #fff;
margin-bottom: 20px;
}
.v-enter-active,
.-leave-active {
transition: all 200ms ease-in;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
transform: translateY(-30px);
}
</style>再改造一下入口文件
之前我們發(fā)現在 app.vue 中調用一次 message方法,就會一次 dom 操作,那我們使用閉包寫一個單例模式進行改造
再者我們在 Message.vue 暴露出add的方法可以直接進行操作消息列表
// index.js
import { render, createVNode } from 'vue'
import Message from './Message.vue'
let vm
// 使用單例模式,不再重新插入body
function getMessageInstance () {
if (vm) return
const div = document.createElement('div')
vm = createVNode(Message)
render(vm, div)
document.body.appendChild(div)
}
export default function message (content = '', duration) {
getMessageInstance()
vm.component.exposed.add({
content,
duration
})
}最后在 app.vue 文件中隨便編寫一些測試代碼
<!-- app.vue -->
<template>
<button @click="onClick">測試</button>
</template>
<script>
import message from './components/message'
export default{
setup() {
message('消息組件1', 4)
message('消息組件2', 2)
let index = 3
const onClick = () => {
message(`消息組件${index++}`)
}
return {
onClick
}
}
}
</script>看看最終效果

好,這就是全局提示組件設計大致思路。
回顧一下會發(fā)現,其實Vue的組件開發(fā)依舊繞不開 JavaScript,可見 JavaScript 在前端的份量。
總結
到此這篇關于Vue全局提示組件的文章就介紹到這了,更多相關Vue全局提示組件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在vue中nextTick用法及nextTick 的原理是什么
這篇文章主要介紹了在vue中nextTick用法及nextTick 的原理是什么,Vue.js 是一個流行的前端框架,它提供了一種響應式的數據綁定機制,使得頁面的數據與頁面的 UI 組件之間能夠自動同步,需要的朋友可以參考下2023-04-04
vue router使用query和params傳參的使用和區(qū)別
本篇文章主要介紹了vue router使用query和params傳參的使用和區(qū)別,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11
前端實現簡單的sse封裝方式(React hook Vue3)
這篇文章主要介紹了前端實現簡單的sse封裝方式(React hook Vue3),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue讀取本地靜態(tài)文件json的2種方法以及優(yōu)缺點
這篇文章主要介紹了Vue讀取本地靜態(tài)文件json的2種方法以及優(yōu)缺點說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09

