问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Vue3TypeScript全局Message提示框

发布网友 发布时间:2024-10-05 06:58

我来回答

1个回答

热心网友 时间:2024-12-14 19:06

前言

实现过一个vue2+ts下的全局的Message提示框。闲暇之余想在vue3+ts的框架下也实现此功能。

技术思路

在vue3上的实现思路

install函数是把编写的Message组件实例化并渲染到页面的关键。其中的步骤:

根据Message组件实例化一个Message

在document.body上appendChild实例

同时返回一个destory函数用于手动销毁实例

倒计时时间到销毁实例

编写Message组件代码//Mssage.vue<template><transitionname="slide"><div:class="[type,center?'text-center':'']":style="{...style}"v-if="visible"><divv-if="messageArr.length"><divv-for="(item,index)inmessageArr":key="index">{{item}}</div></div><divv-else>{{message}}</div></div></transition></template><script>import{defineComponent}from'vue';exportdefaultdefineComponent({props:{message:{type:String,default:'',},type:{type:String,default:'success',},ration:{type:Number,default:2000,},},data(){constmessageArr:Array<string>=[];conststyle={};return{messageArr,visible:true,center:false,style,};},created():void{constarr=this.message.split('\n');if(arr.length>1){this.messageArr=arr;}},mounted():void{this.startTimer();},methods:{startTimer():void{const{ration}=this;consttimer=setTimeout(()=>{this.visible=false;clearTimeout(timer);},ration);},},});</script>编写install函数并挂载到vue全局//index.tsimport{App,render,createVNode}from'vue';importMessagefrom'./Message.vue';constdefaultOpt={//创建默认参数ration:2000,type:'success',};//消息数组conststack:Array<HTMLDivElement>=[];/***@description:销毁body上的Message实例*@param{HTMLDivElement}ele*@return{*}*/constremoveContainer=(ele:HTMLDivElement):void=>{constindex=stack.findIndex((item)=>item===ele);if(~index){stack.splice(index,1);setStyle();}};/***@description:把实例加到实例队列stack中,并设置队列中搜有实例的style*@param{HTMLDivElement}ele*@return{*}*/constaddContainer=(ele:HTMLDivElement):void=>{stack.push(ele);setStyle();};/***@description:设置stack中所有实例的style*@param{*}*@return{*}*/constsetStyle=()=>{stack.forEach((item,index)=>{if(item?.getElementsByClassName('message-wrap')?.[0]){lettop=0;if(index>0){top+=(stack[index-1].getElementsByClassName('message-wrap')[0]asHTMLElement)?.getBoundingClientRect()?.bottom||0;}//eslint-disable-next-line(item.getElementsByClassName('message-wrap')[0]asHTMLElement).style.marginTop=`${top}px`;}});};//创建挂载实例//eslint-disable-next-lineconstcreateMount=(opts:{[key:string]:any})=>{const{ration}=opts;//创建一个div容器constcontainer=document.createElement('div');//创建Message实例,createVNode的性能比h更好constvm=createVNode(Message,opts);//把实例render到容器上render(vm,container);addContainer(container);//把容器渲染到body上document.body.appendChild(container);constdestory=()=>{consttimer=setTimeout(()=>{render(null,container);removeContainer(container);document.body.removeChild(container);clearTimeout(timer);},500);//500为动画结束时间,根据情况修改};consttimer=setTimeout(()=>{destory();clearTimeout(timer);},ration||defaultOpt.ration);return{destory};};functionToast(options:{message:string;ration?:number}|string):{destory:()=>void;}{if(typeofoptions==='string'){//eslint-disable-next-lineoptions={...defaultOpt,message:options||'',};}else{//eslint-disable-next-lineoptions={...defaultOpt,...options,};}returncreateMount(options);}Toast.install=(app:App<Element>)=>{app.component('toast',Message);app.provide('Toast',Toast);//挂载Toast为全局方法$toast//eslint-disable-next-lineapp.config.globalProperties.$toast=Toast;};exportdefaultToast;use为全局组件;增加$toast声明,消除使用时的ts报错import{createApp}from'vue';importToastfrom'@/components/toast';constapp=createApp(App);app.use(Toast);app.mount('#app');//定义了全局方法之后需要扩充类型declaremole'@vue/runtime-core'{interfaceComponentCustomProperties{$toast:typeofToast;}}使用this.$toast('message');this.$toast({message:'message',tation:5000,})和vue2上的对比vue2vue3创建方式1.先创建构造函数constMessageBox=Vue.extend(MessageComp);2.通过构造函数实例化对象constinstance:any=newMessageBox({data:options,}).$mount();1.先创建一个div容器constcontainer=document.createElement('div');2.createVNode创建组件实例constvm=createVNode(Message,opts);3.把实例render到容器上render(vm,container);tips

vue2版本?:https://juejin.cn/post/7015199722805657631

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
便携式发电机十大名牌 冬天夜跑同时锻炼身体和意志的句子锦集 冬天的时候跑步可以达到46~60分钟 可是夏天了跑步25分钟左右就已经感觉... 孩子病毒性感冒咳嗽厉害怎么办 严重的病毒性感冒几天能好 宝宝六个月因为病毒性感冒而咳嗽有痰可每次咳嗽出来的痰他吐不出来怎 ... ios购买的app怎么退款 求助!书法高手!用什么书法来“魏亮”这二字最漂亮? 万事胜意,喜乐长安繁体 什么叫喜乐长安 有哪些品牌的补水喷雾补水效果好? 宋朝什么窑最出名 宋朝有什么瓷器 宋朝的十大文物 软著申请对源代码要求是什么 软著申请源代码格式要求 洗衣服时把白衣服染上颜色了该怎么办?拜托各位了 3Q 软件著作权申请软件著作权登记流程 怎么可以把染色的衣服洗干净 mac OS amd64汇编入门(一): 数据类型 Mac入门使用教程如何把我的Windows使用习惯延续到Mac上来 Mac新手入门指南 大家的瑞纳都买的什么样的座套? 女友坦白自己不是处女,我该怎么办? 瑞纳车坐靠枕不能拆怎么安座套 辽源田雨小镇旅游攻略,辽源旅游攻略路线推荐 恋爱之前女友主动说自己不是处女,怎么办? 乐扣的杯子盖子里的橡皮圈都是断裂的吗? 记得以前有个软件,叫自动说说名片赞,点开后是整人的,贞子的图片,一直叫... 我想刷掉别人赞我名片的人,请问有什么办法可以做到 杯子里面的橡皮圈老掉怎么班啊? 宋朝官窑有哪些 宋朝什么文物最值钱 韩国保湿喷雾哪个牌子好 笔记本电脑开机闪屏是什么问题? Excel表格怎么设置条形图的名称左对齐和自动更新图形数据 小米路由器备份照片失败是怎么回事 为什么女的要男的请吃饭 sanpowa是什么品牌 photoshop cs3名片制作尺寸问题 拉柏家雅品牌 原微信账号被封就用同一个电话号码又注册了个微信号,可是愿微信账号就登... WPS word怎么取消目录? 鼻子塞止血棉条睡不着怎么办 win7瘦身工具精简教程 员工试用期内辞职是否承担责任 晋城市高平德邦物流召工 头顶左侧一跳一跳的疼怎么回事 左边头顶疼怎么回事 左侧头顶痛是什么原因 头顶左侧阵痛是什么原因