日常开发中经常会使用到提示信息框,例如:接口调用失败需告知失败信息,用户点击加入购物车需告知用户加入成功等。若每次单独写,则非常繁琐,且没必要。因为此功能和页面整体的耦合性不强,因此可以单独拿出来做一个插件。
因为此插件可以挂载到Vue的原型上,可以十分方便的使用:
// 使用示例
this.$toast.info('this is a message', 3000)
使用效果:
插件源码
示例源码
由于这个提示框和页面并不耦合,因此可以将其提取出来,新建一个.vue文件,主要用于创建一个组件,确定布局,样式等。
toast.vue
<template>
<transition name="toast-fade">
<div class="toast" v-show="showToast">
<img :src="img" class="icon" alt="">
<span class="text">{{message}}</span>
</div>
</transition>
</template>
<script>
export default {
name: 'toast',
data() {
return {
showToast: false,
message: 'a message',
type: 'info',
duration: 3000
}
},
computed: {
// 不同的提示类型使用不同的提示图片
img() {
let imglink = ''
switch (this.type) {
case 'info':
imglink = require('@res/icon/hint-b.svg')
break;
case 'warn':
imglink = require('@res/icon/hint-y.svg')
break;
case 'success':
imglink = require('@res/icon/hint-g.svg')
break;
case 'error':
imglink = require('@res/icon/hint-r.svg')
break;
default:
imglink = require('@res/icon/hint-b.svg')
break;
}
return imglink
}
},
beforeDestroy() {
this.$el && documen.body.removeChild($el)
},
methods: {
show() {
// 元素添加到DOM中
document.body.appendChild(this.$el)
this.showToast = true
setTimeout(() => {
this.showToast = false
}, this.duration);
}
}
};
</script>
<style scoped lang="scss">
.toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 999;
background: #333;
border-radius: .1rem;
font-size: .15rem;
padding: .1rem .2rem;
color: #ffffff;
display: flex;
&.toast-fade-enter-active {
animation: toast-fadein 0.3s;
}
&.toast-fade-leave-active {
animation: toast-fadeout .3s;
}
.icon{
width: .2rem;
height: .2rem;
margin-right: .06rem;
vertical-align: bottom;
}
}
@keyframes toast-fadein {
0% {opacity: 0;}
100% {opacity: 1;}
}
@keyframes toast-fadeout {
0% {opacity: 1;}
100% {opacity: 0;}
}
</style>
创建一个js文件,利用Vue.extend()来动态创建toast组件。
toast/index.js
import Vue from 'vue'
import Toast from '@com/toast.vue'; // 引入组件
const TOAST = Vue.extend(Toast)
// 创建Toast实例并挂载此实例
let instance
const initInstance = () => {
instance = new TOAST
instance.$mount()
}
// 控制组件的展示
function showMsg(message, type, duration) {
duration = duration && parseInt(duration) && parseInt(duration) > 0 ? parseInt(duration) : 3000
const typeList = ['info', 'warn', 'success', 'error']
type = typeList.includes(type)? type : 'info'
instance || initInstance()
// 将外部传入的message等信息传入到组件实例中
const toast = Object.assign(instance, {
message,
type,
duration,
})
// 调用实例的show()方法,实现组件的展示
toast.show()
return this
}
// 将调用方法暴露出去
export default {
info(msg, duration) {
showMsg(msg, 'info', duration)
},
success(msg, duration) {
showMsg(msg, 'success', duration)
},
warn(msg, duration) {
showMsg(msg, 'warn', duration)
},
error(msg, duration) {
showMsg(msg, 'error', duration)
},
}
最后将此方法挂载到Vue的原型上
import Toast from './plugins/toast/index';
Vue.prototype.$toast = Toast;
使用方法:
//使用方法:
@param: {String} msg 提示信息
@param: {Number} duration 停留时间(ms)
this.$toast.info(msg, duration) // 普通提示信息
this.$toast.warn(msg, duration) // 警告信息
this.$toast.error(msg, duration) // 错误信息
this.$toast.success(msg, duration) // 成功信息