怎么封装一个更易用的dialog组件-亚博电竞手机版
开发技术
2022年05月19日 10:36
2
怎么封装一个更易用的dialog组件
这篇“怎么封装一个更易用的dialog组件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么封装一个更易用的dialog组件”文章吧。
场景
在项目中,我们经常会遇到使用弹窗的场景,但有时组件库自带的弹窗不能满足我们的需求,需要我们自己封装,这时我们如何去自定义一个更加方便调用的弹窗?
搭建环境
首先我们需要搭建一个vue3 ts的环境。
用vite的官方模板:
yarncreatevitedemo-app--templatevue-ts
进入并安装依赖
cddemo-appyarn
依赖安装完成后启动app
yarndev
创建组件
先在src/components目录下创建mydialog.vue,搭建一个组件的基本框架
import{ref,reactive}from"vue";defineprops({message:{type:string,default:"",},title:{type:string,default:"",},});constemits=defineemits<{(e:"confirm"):void;(e:"close"):void;}>();constvisible=ref(true);functionclickconfirm(){console.log("确认");emits("confirm");}functionclickclose(){console.log("取消");emits("close");} {{title}} {{message}}.wrap{position:absolute;top:0;left:0;background:rgba(15,15,15,0.5);width:100%;height:100%;}.container{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);min-width:300px;min-height:200px;padding:10px;background:white;display:flex;flex-direction:column;}.content{flex:1;padding:10px;text-align:left;}.title{min-height:30px;}.controll{display:flex;width:100%;justify-content:space-around;}
创建调用组件的hook函数
在src目录下创建hooks目录,然后再hooks目录下创建usemydialog.ts.
函数调用组件我们需要:
将组件转换成vnode
将vnode转换成dom然后渲染到页面
import{createvnode,render,componentpublicinstance}from"vue";exportdefaultfunctionusemydialog(option?:any){constprops={...option,};constvm=createvnode(mydialog,props);constcontainer=document.createelement("div");render(vm,container);document.queryselector("#app")?.appendchild(container.firstelementchild!);}
ps:
container.firstelementchild!中的!表示container.firstelementchild不为null或者undefined
接下来我们在app.vue中测试一下
importusemydialogfrom"./hooks/usemydialog";functionshowdialog(){usemydialog({message:"test1",onclose:()=>{console.log("self");},});} 显示dialog
dialog的缓存、隐藏
隐藏
我们需要将close返回出去,这样我们就可以手动调用close函数关闭dialog.
在usemydialog.ts中添加
import{componentpublicinstance,vnode}from"vue";exportdefaultfunctionusemydialog(option?:any){constuserclosefn=option?.onclose;props.onclose=()=>{close();userclosefn??userclosefn();};functionclose(vm:vnode){(vm.component!.proxyascomponentpublicinstance<{visible:boolean}>).visible=false;}return{close:close.bind(null,vm),}}
缓存
现在每次点击显示dialog按钮时都会创建一个新的组件实例,这不是我们的预期,所以我们需要将组件进行缓存.
在usemydialog.ts中添加
import{componentpublicinstance}from'vue'constinstances:any[]=[];exportdefaultfunctionusemydialog(option?:any){consttempvm:any=instances.find((item)=>`${item.vm.props?.message??""}`===`${(optionasany).message??""}`);if(tempvm){(tempvm.vm.component!.proxyascomponentpublicinstance<{visible:boolean;}>).visible=true;return{close:close.bind(null,tempvm.vm),};}}
完整代码
src/hooks/usemydialog.ts
import{createvnode,render,componentpublicinstance,vnode}from"vue";importmydialogfrom"../components/mydialog.vue";constinstances:any[]=[];exportdefaultfunctionusemydialog(option?:any){constprops={...option,};constuserclosefn=option?.onclose;props.onclose=()=>{close(vm);userclosefn??userclosefn();};functionclose(vm:vnode){(vm.component!.proxyascomponentpublicinstance<{visible:boolean}>).visible=false;}consttempvm:any=instances.find((item)=>`${item.vm.props?.message??""}`===`${(optionasany).message??""}`);if(tempvm){(tempvm.vm.component!.proxyascomponentpublicinstance<{visible:boolean;}>).visible=true;return{close:close.bind(null,tempvm.vm),};}constvm=createvnode(mydialog,props);constcontainer=document.createelement("div");render(vm,container);document.queryselector("#app")?.appendchild(container.firstelementchild!);instances.push({vm});return{close:close.bind(null,vm),};}
以上就是关于“怎么封装一个更易用的dialog组件”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注恰卡编程网行业资讯频道。
展开全文