怎么封装一个更易用的Dialog组件

怎么封装一个更易用的Dialog组件

这篇“怎么封装一个更易用的Dialog组件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么封装一个更易用的Dialog组件”文章吧。

    场景

    在项目中,我们经常会遇到使用弹窗的场景,但有时组件库自带的弹窗不能满足我们的需求,需要我们自己封装,这时我们如何去自定义一个更加方便调用的弹窗?

    搭建环境

    首先我们需要搭建一个Vue3+ts的环境。

    用vite的官方模板:

    yarncreatevitedemo-app--templatevue-ts

    进入并安装依赖

    cddemo-appyarn

    依赖安装完成后启动app

    yarndev

    创建组件

    先在src/components目录下创建MyDialog.vue,搭建一个组件的基本框架

    <scriptlang="ts"setup>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");}</script><template><divclass="wrap"v-if="visible"><divclass="container"><divclass="title">{{title}}</div><divclass="content"><div>{{message}}</div></div><divclass="controll"><button@click="clickConfirm">确认</button><button@click="clickClose">取消</button></div></div></div></template><stylescoped>.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;}</style>

    创建调用组件的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中测试一下

    <scriptsetuplang="ts">importuseMyDialogfrom"./hooks/useMyDialog";functionshowDialog(){useMyDialog({message:"test1",onClose:()=>{console.log("self");},});}</script><template><button@click="showDialog">显示Dialog</button></template>

    Dialog的缓存、隐藏

    隐藏

    我们需要将close返回出去,这样我们就可以手动调用close函数关闭Dialog.

    在useMyDialog.ts中添加

    import{ComponentPublicInstance,VNode}from"vue";exportdefaultfunctionuseMyDialog(option?:any){constuserCloseFn=option?.onClose;props.onClose=()=&gt;{close();userCloseFn??userCloseFn();};functionclose(vm:VNode){(vm.component!.proxyasComponentPublicInstance&lt;{visible:boolean}&gt;).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组件”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注恰卡编程网行业资讯频道。

    发布于 2022-05-19 10:36:39
    收藏
    分享
    海报
    0 条评论
    29
    上一篇:怎么使用pytorch读取数据集 下一篇:Spring Boot条件注解怎么用
    目录

      0 条评论

      本站已关闭游客评论,请登录或者注册后再评论吧~

      忘记密码?

      图形验证码