作者: | 来源:互联网 | 2023-10-11 22:52
vue3.x全局toast、message、loading组件Toast组件loadingToast组件在srccomponents下创建toast文件夹,并依此创
vue3.x全局toast、message、loading组件
Toast组件
- 在 src/components下创建toast文件夹,并依此创建index.vue和index.js
1、index.vue
一般toast会有如下功能:背景色、字体颜色、文本、停留时间
<template>
<div class&#61;"toast-box" ><p class&#61;"toast-value" :style&#61;"{background: background, color: color}">{{ value }}</p>
</div>
</template>
<script>import { defineComponent } from &#39;vue&#39;export default defineComponent({name: &#39;Toast&#39;,props: {value: {type: String,default: &#39;&#39;},duration: {type: Number,default: 3000},background: {type: String,default: &#39;#000&#39;},color: {type: String,default: &#39;#fff&#39;}}})
</script><style>
.toast-box {position: fixed;width: 100vw;height: 100vh;top: 0;left: 0;display: flex;align-items: center;justify-content: center;z-index: 1000;
}.toast-value {max-width: 100px;background: rgb(8, 8, 8);padding: 8px 10px;border-radius: 4px;text-align: center;display: inline-block;animation: anim 0.5s;}&#64;keyframes anim { 0% {opacity: 0;}100%{opacity:1;}}.toast-value.remove{animation: remove 0.5s;}&#64;keyframes remove { 0% {opacity: 1;}100%{opacity:0;}}
</style>
2、index.js 导出Toast方法
以下代码为TS写法&#xff0c;不支持部分去掉代码即可
import { createVNode, render } from &#39;vue&#39;
import toastTemplate from &#39;./index.vue&#39;
export interface IProps {value?: string;duration?: number;background?: string;color?: string;
}
const defaultOpt &#61; { duration: 3000
}export interface ResultParams {destory?: () &#61;> void;
}
const Toast &#61; (options: IProps):ResultParams &#61;> {const container &#61; document.createElement(&#39;div&#39;)const opt &#61; {...defaultOpt,...options}const vm &#61; createVNode(toastTemplate, opt) render(vm, container)document.body.appendChild(container) const destory &#61; ()&#61;> {const dom &#61; vm.el as HTMLDivElementif(dom.querySelector(&#39;.toast-value&#39;)) {dom.querySelector(&#39;.toast-value&#39;)?.classList.add(&#39;remove&#39;) const t &#61; setTimeout(() &#61;> { render(null, container)document.body.removeChild(container)clearTimeout(t)},500);} }if(opt.duration) { const timer &#61; setTimeout(()&#61;> {destory()clearTimeout(timer)}, opt.duration)}return {destory}
}
export default Toast
3、main.js插件全局引入
import Toast from &#39;&#64;/components/Toast/index&#39;app.config.globalProperties.$toast &#61; Toast;
4、使用
this.$toast({value: &#39;toast&#39;,duration: 0, // 如果大于0则不必使用destory方法background: &#39;#000&#39;,color: &#39;#fff&#39;
})
setTimeout(() &#61;> {this.$toast.destory && this.$toast.destory()
}, 2000)
setup内使用
import { getCurrentInstance} from &#39;vue&#39;setup() {const { proxy } &#61; getCurrentInstance();const showToastEvent &#61; () &#61;> {proxy.$toast({value: &#39;toast&#39;,duration: 1000,background: &#39;#000&#39;,color: &#39;#fff&#39;})}return {showToastEvent,}
}
loading
<template><div class&#61;"loading">加载中...</div>
</template><script>export default {name: "loading",}
</script><style scoped>.loading {position: fixed;left: 50%;top: 50%;background-color: rgba(0, 0, 0, 0.2);color: white;transform: translate(-50%, -50%);border-radius: 4px;padding: 8px 10px;z-index: 1000;}
</style>
import { createApp } from "vue"import Loading from &#39;./loading.vue&#39;export default {instance: null,parent: null,times: 0, open() {if (this.times &#61;&#61; 0) {this.instance &#61; createApp(Loading)this.parent &#61; document.createElement("div")let appDom &#61; document.getElementById(&#39;app&#39;)appDom.appendChild(this.parent)this.instance.mount(this.parent)}this.times &#43;&#43;},close() {this.times --if (this.times <&#61; 0) {this.times &#61; 0let appDom &#61; document.getElementById(&#39;app&#39;)this.instance.unmount(this.parent)appDom.removeChild(this.parent)}}
};
import loading from &#39;&#64;/components/loading/index&#39;
app.config.globalProperties.$loading &#61; loading;