vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法詳解
本文實(shí)例講述了vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法。分享給大家供大家參考,具體如下:
利用vue從零實(shí)現(xiàn)一個(gè)消息通知組件
平時(shí),我們肯定用過類似element-ui,antd等一些UI框架,感受它們帶給我們的便利。但當(dāng)我們的需求或者設(shè)計(jì)這些框架內(nèi)置的相差太大,用起來,就會(huì)覺得特別別扭,這時(shí)候,就有必要自己來重新造輪子。
重新造輪子,有幾個(gè)好處,1.所有代碼都是服務(wù)你的業(yè)務(wù),沒有太多用不上的東西。2.代碼是由自己維護(hù),而不是第三方,方便維護(hù)。3.提升自己的視野,讓自己站在更高的角度來看問題。
好了,那話不多說,開始我們的組件開發(fā)吧!
文件目錄的組件
工欲善其事,必先利其器,要想實(shí)現(xiàn)一個(gè)組件,一個(gè)好的目錄結(jié)構(gòu),即可以劃分職責(zé),不同模塊處理不同的邏輯!
我的目錄結(jié)果是這樣的:

接下來,我們依次對(duì)notification.vue, notify.js, index.js三個(gè)文件作介紹。
notification.vue
notification.vue是一個(gè)負(fù)責(zé)消息通知組件的視覺呈現(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)消息的無縫滾動(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自定義全局消息框組件問題
- Vue中消息橫向滾動(dòng)時(shí)setInterval清不掉的問題及解決方法
- vue 自定義組件的寫法與用法詳解
- vue2.0 自定義組件的方法(vue組件的封裝)
相關(guān)文章
vite結(jié)合electron構(gòu)建前端桌面應(yīng)用程序
本文主要介紹了vite結(jié)合electron構(gòu)建前端桌面應(yīng)用程序,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
在Vue環(huán)境下利用worker運(yùn)行interval計(jì)時(shí)器的步驟
這篇文章主要介紹了在Vue環(huán)境下利用worker運(yùn)行interval計(jì)時(shí)器的步驟,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
vue解決使用$http獲取數(shù)據(jù)時(shí)報(bào)錯(cuò)的問題
今天小編就為大家分享一篇vue解決使用$http獲取數(shù)據(jù)時(shí)報(bào)錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-10-10
vue-cli如何修改打包項(xiàng)目結(jié)構(gòu)及前綴
這篇文章主要介紹了vue-cli如何修改打包項(xiàng)目結(jié)構(gòu)及前綴問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07

