vue3封装全局消息提示实例
效果展示
实现
模版
模版部分比较简单,里面就是一个msg,用v-show控制展示,外面再包一个Transition动画组件。
<template>
<Transition>
<div class="toast_wrp" v-show="isShow">
<div :class="['toast_inner', 'toast_inner-' + type]">
{{ msg }}
</div>
</div>
</Transition>
</template>
逻辑代码
包含组件定义和组件注册两块。组件Toast定义比较简单,props参数只需要msg内容和type类型。data中isShow用来控制展示。在组件mounted后,修改isShow字段进行展示。
组件注册部分,使用了vue的createVNode和render函数,并且设置了globalProperties来注册全局函数。
为了把组件挂载到页面上,首先创建一个div节点,并把它插入body中。 然后创建Toast的虚拟节点,并挂载到div上。这样就能在页面上显示出消息组件了。
为了实现消息组件延迟一定时间后自动移除的效果,设置了一个定时器,在默认1000ms后,把空节点挂载到div上。
<script>
import { createVNode, render } from 'vue';
const Toast = {
name: 'mp-toast',
props: {
msg: {
// toast 显示的wording
type: String,
default: '',
},
// 类型, success/error
type: {
type: String,
default: 'success',
},
},
data() {
return {
isShow: false,
};
},
mounted() {
this.isShow = true;
},
};
// 创建消息提示节点
const div = document.createElement('div');
document.body.appendChild(div);
const Message = ({ msg, type, duration }) => {
let timer = null;
// 渲染虚拟节点
const vnode = createVNode(Toast, { msg, type, duration });
render(vnode, div);
clearTimeout(timer);
// 渲染空节点
timer = setTimeout(() => {
render(null, div);
}, duration || 1000);
};
Toast.install = (app) => {
// 注册全局属性
app.config.globalProperties.$message = Message;
};
export default Toast;
</script>
样式
.toast_wrp {
background-color: white;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
opacity: 1;
visibility: visible;
z-index: 50000;
transition: all 0.2s 0.2s;
}
.toast_inner {
padding: 16px 32px;
color: white;
font-size: 17px;
font-weight: 500;
border-radius: 10px;
border: 1px solid white;
}
.toast_inner-success {
background: rgb(240, 249, 235);
border-color: rgb(225, 243, 216);
color: #67c23a;
}
.toast_inner-error {
background: rgb(254, 240, 240);
border-color: rgb(253, 226, 226);
color: #f56c6c;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
transform: translate3d(0, -75px, 0);
opacity: 0;
}
使用
组件需要在全局注册,使用app.use()。
import { createApp } from 'vue';
import App from './App.vue';
import Toast from './components/Toast.vue';
const app = createApp(App);
// 注册Toast组件
app.use(Toast);
app.mount('#app');
注册了之后,在其它地方使用this.$message()就可以创建一个消息实例了。
也可以在setup函数中访问组件实例对象
import { getCurrentInstance } from 'vue'
setup(){
const instance= getCurrentInstance();
instance.proxy.$message({ msg: '复制失败', type: 'error' })
}