一起來做一下Vue全局提示組件
全局提示組件在前端中算是比較重要的,在開發(fā)業(yè)務時候肯定能用的上,畢竟任何報錯只要提示“服務器異常”就可以完美把鍋扔給后臺(手動滑稽)
全局提示組件在人氣比較??的 UI 組件庫必有他身影,可能叫法不太相同,有叫 message、toast、alert 等,但就是這么一玩意。
拿 ant-design-vue 組件庫為例
其核心代碼
message.info('This is a normal message')
他是API的方式進行調(diào)用組件,以平常使用components注冊組件,之后在template中使用的方式不太相同
想要實現(xiàn)這個,其實并不困難
但在之前我想聲明一下:ant-design-vue 的 message 做個type分類,有info、success、error等。但為了讀者方便理解,我們統(tǒng)一就用message來進行調(diào)用,讀者可以根據(jù)本文提供的demo源碼自行進行調(diào)整(貼一下 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,這樣就實現(xiàn)了以API的方式進行調(diào)用組件
其核心代碼其實只有以下
const div = document.createElement('div') const vm = createVNode(Message, { content }) render(vm, div) document.body.appendChild(div)
createVNode 可以認為就是h函數(shù),支持直接轉(zhuǎn)成虛擬dom對象
再去調(diào)用 render,渲染至div下,再將div插入body中
由于我們做的是全局組件,應該不被任何因素干擾,比如 vue-router
但是上面例子我們會發(fā)現(xiàn),我們只要調(diào)用一個 message 方法,就要創(chuàng)建一個div插入至body,這顯然不是符合vue數(shù)據(jù)驅(qū)動視圖的理念
那,接下里進行改造
先從 Message.vue 文件開始
我們先定義一個消息列表messages,之后提供添加 add 和刪除delete消息列兩方法,再暴露add方法出去
當然,刪除消息是需要根據(jù)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) } // 根據(jù) 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ā)現(xiàn)在 app.vue 中調(diào)用一次 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ā)現(xiàn),其實Vue的組件開發(fā)依舊繞不開 JavaScript,可見 JavaScript 在前端的份量。
總結
到此這篇關于Vue全局提示組件的文章就介紹到這了,更多相關Vue全局提示組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue-cli整合vuex的時候,修改actions和mutations,實現(xiàn)熱部署的方法
今天小編就為大家分享一篇vue-cli整合vuex的時候,修改actions和mutations,實現(xiàn)熱部署的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue+webrtc(騰訊云) 實現(xiàn)直播功能的實踐
本文主要介紹了vue+webrtc(騰訊云) 實現(xiàn)直播功能的實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11