利⽤vue从零实现⼀个消息通知组件
利⽤vue从零实现⼀个消息通知组件
平时,我们肯定⽤过类似element-ui,antd等⼀些UI框架,感受它们带给我们的便利。但当我们的需求或者设计这些框架内置的相差太⼤,⽤起来,就会觉得特别别扭,这时候,就有必要⾃⼰来重新造轮⼦。
重新造轮⼦,有⼏个好处,1.所有代码都是服务你的业务,没有太多⽤不上的东西。2.代码是由⾃⼰维护,⽽不是第三⽅,⽅便维护。3.提升⾃⼰的视野,让⾃⼰站在更⾼的⾓度来看问题。
好了,那话不多说,开始我们的组件开发吧!
⽂件⽬录的组件
⼯欲善其事,必先利其器,要想实现⼀个组件,⼀个好的⽬录结构,即可以划分职责,不同模块处理不同的逻辑!
我的⽬录结果是这样的:
接下来,我们依次对notification.vue, notify.js, index.js三个⽂件作介绍。
notification.vue
notification.vue是⼀个负责消息通知组件的视觉呈现,⾥⾯的逻辑很简单。
<template>
<transition name="fade" @after-enter="handleAfterEnter">
<div class="notification" : v-show="visible">
在线翻译词典<span class="notification__content">
{{content}}
</span>
<span class="notification__btn" @click="handleClo">{{btn}}</span>
</div>
</transition>
</template>
航空学校分数线
<script>
export default {
name: 'Notification',
props: {
content: {
bustype: String,
required: true
},
btn: {
type: String,
default: '关闭'
}
}
}
</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是⼀个处理消息通知组件的逻辑部分,其主要作⽤是暴露⼀个notify的⽅法出去。代码如下:
import Vue from 'vue'
import Notification from './notification'
考研现场确认需要带什么
const NotificationConstructor = d(Notification)
const instances = []
let ed = 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].verticalOfft = parInt(instances[i].verticalOfft) - removeHeight - 16 }
}
const notify = (options = {}) => {
if (Vue.prototype.$isServer) return
// 获取vue实例
let instance = new NotificationConstructor({
propsData: options,
data() {
return {
verticalOfft: 0,
timer: null,
科比追悼会主题visible: fal,
height: 0
}
},
computed: {
style() {
return {
position: 'fixed',
right: '20px',
bottom: `${this.verticalOfft}px`
}
}
},
mounted() {
this.$el.addEventListener('mouenter', () => {
if (this.timer) {
this.clearTimer(this.timer)
}
})
this.$el.addEventListener('mouleave', () => {
if (this.timer) {
this.clearTimer(this.timer)
}
})
},
updated() {
this.height = this.$el.offtHeight
},
beforeDestroy() {
this.clearTimer()
},
methods: {
createTimer() {
this.timer = tTimeout(() => {
this.visible = fal
veChild(this.$el)
removeInstance(this)
this.$destroy()
}, options.timeout || 3000)
},
clearTimer() {
if (this.timer) {
clearTimeout(this.timer)incredible什么意思
}
},
handleClo() {
this.visible = fal
veChild(this.$el)
removeInstance(this)
this.$destroy(true)
uptting},
handleAfterEnter() {
// eslint-disable-next-line no-debugger
this.height = this.$el.offtHeight
}
}
})
const id = `notification_${ed++}`
重庆环球雅思
instance.id = id
// ⽣成vue中的$el
instance = instance.$mount()
// 将$el中的内容插⼊dom节点中去
document.body.appendChild(instance.$el)
instance.visible = true
// eslint-disable-next-line no-unud-vars
let verticalOfft = 0
instances.forEach(item => {
verticalOfft += item.$el.offtHeight + 16
})
verticalOfft += 16
instance.verticalOfft = verticalOfft
instances.push(instance)
return instance
}
export default notify
index.js
index.js主要是对notification.vue组件实现注册,notify⽅法的挂载。代码如下:
import Notification from './notification'
import notify from './notify'
export default (Vue) => {
Vue.prototype.$notify = notify
}
在main.js引⼊
import Notification from './components/notification'
Vue.u(Notification)
使⽤
this.$notify({
content: 'Hello' })
效果