vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法詳解
本文實(shí)例講述了vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法。分享給大家供大家參考,具體如下:
利用vue從零實(shí)現(xiàn)一個(gè)消息通知組件
平時(shí),我們肯定用過(guò)類似element-ui,antd等一些UI框架,感受它們帶給我們的便利。但當(dāng)我們的需求或者設(shè)計(jì)這些框架內(nèi)置的相差太大,用起來(lái),就會(huì)覺(jué)得特別別扭,這時(shí)候,就有必要自己來(lái)重新造輪子。
重新造輪子,有幾個(gè)好處,1.所有代碼都是服務(wù)你的業(yè)務(wù),沒(méi)有太多用不上的東西。2.代碼是由自己維護(hù),而不是第三方,方便維護(hù)。3.提升自己的視野,讓自己站在更高的角度來(lái)看問(wèn)題。
好了,那話不多說(shuō),開(kāi)始我們的組件開(kāi)發(fā)吧!
文件目錄的組件
工欲善其事,必先利其器,要想實(shí)現(xiàn)一個(gè)組件,一個(gè)好的目錄結(jié)構(gòu),即可以劃分職責(zé),不同模塊處理不同的邏輯!
我的目錄結(jié)果是這樣的:
接下來(lái),我們依次對(duì)notification.vue, notify.js, index.js三個(gè)文件作介紹。
notification.vue
notification.vue是一個(gè)負(fù)責(zé)消息通知組件的視覺(jué)呈現(xiàn),里面的邏輯很簡(jiǎn)單。
<template> <transition name="fade" @after-enter="handleAfterEnter"> <div class="notification" :style="style" v-show="visible"> <span class="notification__content"> {{content}} </span> <span class="notification__btn" @click="handleClose">{{btn}}</span> </div> </transition> </template> <script> export default { name: 'Notification', props: { content: { type: String, required: true }, btn: { type: String, default: '關(guān)閉' } } } </script> <style lang="less" scoped> .fade-enter-active, .fade-leave-active{ transition: opacity 1s; } .fade-enter, .fade-leave-to{ opacity: 0; } .notification{ display: flex; background-color: #303030; color: rgba(255, 255, 255, 1); align-items: center; padding: 20px; position: fixed; min-width: 280px; box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.3); flex-wrap: wrap; transition: all 0.3s; &__content{ padding: 0; } &__btn{ color: #ff4081; padding-left: 24px; margin-left: auto; cursor: pointer; } } </style>
notify.js
notify.js是一個(gè)處理消息通知組件的邏輯部分,其主要作用是暴露一個(gè)notify的方法出去。代碼如下:
import Vue from 'vue' import Notification from './notification' const NotificationConstructor = Vue.extend(Notification) const instances = [] let seed = 1 const removeInstance = (instance) => { if (!instance) return const len = instances.length const index = instances.findIndex(ins => instance.id === ins.id) instances.splice(index, 1) if (len <= 1) return const removeHeight = instance.height for (let i = index; i < len - 1; i++) { instances[i].verticalOffset = parseInt(instances[i].verticalOffset) - removeHeight - 16 } } const notify = (options = {}) => { if (Vue.prototype.$isServer) return // 獲取vue實(shí)例 let instance = new NotificationConstructor({ propsData: options, data() { return { verticalOffset: 0, timer: null, visible: false, height: 0 } }, computed: { style() { return { position: 'fixed', right: '20px', bottom: `${this.verticalOffset}px` } } }, mounted() { this.createTimer() this.$el.addEventListener('mouseenter', () => { if (this.timer) { this.clearTimer(this.timer) } }) this.$el.addEventListener('mouseleave', () => { if (this.timer) { this.clearTimer(this.timer) } this.createTimer() }) }, updated() { this.height = this.$el.offsetHeight }, beforeDestroy() { this.clearTimer() }, methods: { createTimer() { this.timer = setTimeout(() => { this.visible = false document.body.removeChild(this.$el) removeInstance(this) this.$destroy() }, options.timeout || 3000) }, clearTimer() { if (this.timer) { clearTimeout(this.timer) } }, handleClose() { this.visible = false document.body.removeChild(this.$el) removeInstance(this) this.$destroy(true) }, handleAfterEnter() { // eslint-disable-next-line no-debugger this.height = this.$el.offsetHeight } } }) const id = `notification_${seed++}` instance.id = id // 生成vue中的$el instance = instance.$mount() // 將$el中的內(nèi)容插入dom節(jié)點(diǎn)中去 document.body.appendChild(instance.$el) instance.visible = true // eslint-disable-next-line no-unused-vars let verticalOffset = 0 instances.forEach(item => { verticalOffset += item.$el.offsetHeight + 16 }) verticalOffset += 16 instance.verticalOffset = verticalOffset instances.push(instance) return instance } export default notify
index.js
index.js主要是對(duì)notification.vue組件實(shí)現(xiàn)注冊(cè),notify方法的掛載。代碼如下:
import Notification from './notification' import notify from './notify' export default (Vue) => { Vue.component(Notification.name, Notification) Vue.prototype.$notify = notify }
在main.js引入
import Notification from './components/notification' Vue.use(Notification)
使用
this.$notify({ content: 'Hello' })
效果
希望本文所述對(duì)大家vue.js程序設(shè)計(jì)有所幫助。
- vue使用stompjs實(shí)現(xiàn)mqtt消息推送通知
- vue實(shí)現(xiàn)消息的無(wú)縫滾動(dòng)效果的示例代碼
- Vue結(jié)合SignalR實(shí)現(xiàn)前后端實(shí)時(shí)消息同步
- 用Vue.extend構(gòu)建消息提示組件的方法實(shí)例
- vue彈窗消息組件的使用方法
- 最簡(jiǎn)單的vue消息提示全局組件的方法
- vue 實(shí)現(xiàn)websocket發(fā)送消息并實(shí)時(shí)接收消息
- Vue $mount實(shí)戰(zhàn)之實(shí)現(xiàn)消息彈窗組件
- 解決vue自定義全局消息框組件問(wèn)題
- Vue中消息橫向滾動(dòng)時(shí)setInterval清不掉的問(wèn)題及解決方法
- vue 自定義組件的寫(xiě)法與用法詳解
- vue2.0 自定義組件的方法(vue組件的封裝)
相關(guān)文章
Vue Elenent實(shí)現(xiàn)表格相同數(shù)據(jù)列合并
這篇文章主要為大家詳細(xì)介紹了Vue Elenent實(shí)現(xiàn)表格相同數(shù)據(jù)列合并,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11vue內(nèi)置動(dòng)態(tài)組件component使用示例小結(jié)
component是vue內(nèi)置組件,主要作用為動(dòng)態(tài)渲染組件,這篇文章主要介紹了vue內(nèi)置動(dòng)態(tài)組件component使用示例小結(jié),需要的朋友可以參考下2024-03-03vue如何導(dǎo)出json數(shù)據(jù)為excel表格并保存到本地
這篇文章主要介紹了vue如何導(dǎo)出json數(shù)據(jù)為excel表格并保存到本地問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07vue開(kāi)發(fā)拖拽進(jìn)度條滑動(dòng)組件
這篇文章主要為大家詳細(xì)介紹了vue開(kāi)發(fā)拖拽進(jìn)度條滑動(dòng)組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09vue?parseHTML?函數(shù)拿到返回值后的處理源碼解析
這篇文章主要為大家介紹了vue?parseHTML?函數(shù)拿到返回值后的處理源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07vue常見(jiàn)路由跳轉(zhuǎn)的幾種方式小結(jié)
本文主要介紹了常見(jiàn)路由跳轉(zhuǎn)的幾種方式,主要介紹了四種常見(jiàn)方式,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09element中el-cascader級(jí)聯(lián)選擇器只有最后一級(jí)可以多選
本文主要介紹了element中el-cascader級(jí)聯(lián)選擇器只有最后一級(jí)可以多選,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01vue3使用vue-cli引入windicss報(bào)錯(cuò)Can‘t resolve windi.css問(wèn)題
這篇文章主要介紹了vue3使用vue-cli引入windicss報(bào)錯(cuò)Can‘t resolve windi.css問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03