千家信息网

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

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇"怎么封装一个更易用的Dialog组件"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这
千家信息网最后更新 2026年10月31日怎么封装一个更易用的Dialog组件

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

    场景

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

    搭建环境

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

    用vite的官方模板:

    yarn create vite demo-app --template vue-ts

    进入并安装依赖

    cd demo-appyarn

    依赖安装完成后启动app

    yarn dev

    创建组件

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

    创建调用组件的hook函数

    在src目录下创建hooks目录,然后再hooks目录下创建useMyDialog.ts.

    函数调用组件我们需要:

    • 将组件转换成VNode

    • 将VNode转换成DOM然后渲染到页面

    import { createVNode, render, ComponentPublicInstance } from "vue";export default function useMyDialog(option?: any) {  const props = {    ...option,  };  const vm = createVNode(MyDialog, props);  const container = document.createElement("div");  render(vm, container);  document.querySelector("#app")?.appendChild(container.firstElementChild!);}

    ps:

    container.firstElementChild!中的!表示container.firstElementChild不为null或者undefined

    接下来我们在App.vue中测试一下

    Dialog的缓存、隐藏

    隐藏

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

    在useMyDialog.ts中添加

    import { ComponentPublicInstance,VNode } from "vue";export default function useMyDialog(option?: any) {  const userCloseFn = option?.onClose;  props.onClose = () => {    close();    userCloseFn ?? userCloseFn();  };  function close(vm: VNode) {    (      vm.component!.proxy as ComponentPublicInstance<{ visible: boolean }>    ).visible = false;  }  return {    close: close.bind(null, vm),  }}

    缓存

    现在每次点击显示Dialog按钮时都会创建一个新的组件实例,这不是我们的预期,所以我们需要将组件进行缓存.

    在useMyDialog.ts中添加

    import { ComponentPublicInstance } from 'vue'const instances: any[] = [];export default function useMyDialog(option?: any) {  const tempVm: any = instances.find(    (item) =>      `${item.vm.props?.message ?? ""}` === `${(option as any).message ?? ""}`  );  if (tempVm) {    (      tempVm.vm.component!.proxy as ComponentPublicInstance<{        visible: boolean;      }>    ).visible = true;    return {      close: close.bind(null, tempVm.vm),    };  }}

    完整代码

    src/hooks/useMyDialog.ts

    import { createVNode, render, ComponentPublicInstance, VNode } from "vue";import MyDialog from "../components/MyDialog.vue";const instances: any[] = [];export default function useMyDialog(option?: any) {  const props = {    ...option,  };  const userCloseFn = option?.onClose;  props.onClose = () => {    close(vm);    userCloseFn ?? userCloseFn();  };  function close(vm: VNode) {    (      vm.component!.proxy as ComponentPublicInstance<{ visible: boolean }>    ).visible = false;  }  const tempVm: any = instances.find(    (item) =>      `${item.vm.props?.message ?? ""}` === `${(option as any).message ?? ""}`  );  if (tempVm) {    (      tempVm.vm.component!.proxy as ComponentPublicInstance<{        visible: boolean;      }>    ).visible = true;    return {      close: close.bind(null, tempVm.vm),    };  }  const vm = createVNode(MyDialog, props);  const container = document.createElement("div");  render(vm, container);  document.querySelector("#app")?.appendChild(container.firstElementChild!);  instances.push({ vm });  return {    close: close.bind(null, vm),  };}

    以上就是关于"怎么封装一个更易用的Dialog组件"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

    组件 内容 封装 目录 易用 函数 缓存 场景 文章 环境 知识 篇文章 接下来 这不 代码 价值 会创 大部分 官方 实例 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东猪兼强互联网科技有限公司 哈尔滨大商圈互联网科技有限公司 互联网科技保险 科技互联网项目 美国互联网科技巨头监管 北京互联网络科技有限公司 科技创新互联网企业 碳银互联网科技有限公司 左右互联网络科技 天扬科技互联网广告 北京大学互联网科技怎么样 互联网科技大奖都有哪些公司 乌鲁木齐新华智原互联网科技学校 朱啸虎曾投资哪些互联网科技企业 互联网科技大赛获奖感言 怎样加入科技互联网 易企秀互联网科技是做什么的 中国互联网公司的科技投入 科技互联网专业务虚会材料 互联网企业和网络科技有限公司 蓝思科技飞鸽互联网 新华互联网科技学校 广州互联网络科技有限公司 时间互联网络科技 剑昆互联网络科技有限公司临桂 阿里互联网科技公司 互联网为啥属于高科技 洛阳昕诺飞互联网科技有限公司 南博望互联网科技有限公司 为客找房互联网科技公司怎么样
    0