Vue3 如何实现一个带遮罩的 dialog 对话框(二)

简介: Vue3 如何实现一个带遮罩的 dialog 对话框

六. 神奇的 h 函数


目前我们的 dialog 已经可以出现到我们的页面了,但是现在它的内容都是写死的,不灵活,我们需要按照不同的场景传递不同的文字该如何实现呢?这里又需要请出我们的老朋友,h 函数。

h 函数是可以接收第二个参数的,并且第二个参数的值将被转换成 props 传递给我们的组件。

让我们回到 dialogCreator.ts 文件。我们声明一个类型,准备作为 DialogCreator 内部 constructor 参数的类型。这里我先抛出概念,等等我们一步一步验证。

image.png

并且声明两个类的属性 titlecontent 来准备做为 props 传递给我们的 Dialog.vue 组件。

image.png

我们现在还缺少一个关键的东西,就是取消按钮确定按钮的函数,我们一并声明。(这里需要注意,一般取消按钮就是关闭 dialog 对话框的功能,也就是类本身的 dismiss 方法,所以我们不需要用户额外提供取按钮的函数,只需要提供确定时的回调函数即可。)

1395895c3b8e49a484e05e5e88b1778a_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

这里需要读者仔细品味上图代码的含义。

接下来我们就需要传递 this.optionh 函数即可。

image.png

报错了没关系,是因为我们还没有在 Dialog.vue 组件内部定义 Props

让我们分别从 dialogCreator.ts 文件导出这个 DialogPropsType 类型,再从 Dialog.vue 引入这个类型用来定义 props 即可。

image.png

随即可以看到我们刚刚到报错消失了,说明我们的思路是没问题的。

image.png

七. 改造 Dialog.vue 组件


我们先将之前固定写死的,title 部分和 content 部分替换成我们声明的 props 里的 title

image.png

然后别忘了我们 props 还存放着《确定》和《取消》的的方法。取出来分别放置在这两个按钮身上。

image.png

随便找一个其它页面,测试刚刚的 DialogCreator 类,内容我就随便自己写了

image.png

我们测试一下:

f9532e727d0e432ea1847d7a6e305bec_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

八. 遮罩的关闭效果


现在我们点击遮罩是没办法关闭 dialog 的,效果如下:

4537a8312f8a4785b9f8e9dc51a3b3a0_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

造成这种情况的原因也很简单,因为我们的遮罩没有点击事件,怎么办呢?非常非常简单,给遮罩添加取消 cancelBtn ,也就是 dismiss 方法不就可以了吗?

image.png

测试一下,现在点击遮罩已经可以正常关闭 dialog 了。

68708102f09f43b7af6c3b5cf9a7dcfc_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

九. 修复冒泡造成的 Bug


目前看起来功能已经很棒了,但是目前的代码会造成一个严重的 bug,我们在点击 dialog 本身的时候,由于事件冒泡,会错误的触发遮罩层的方法。

cb0770551d6f414fa98f02a1c3c69154_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

我们验证一下,我们随便编写一个函数,然后绑定到 dialog 组件上。

image.png

注意:这里的 dialog 指的是中间的那个实实在在的对话框本身,不是指整个组件。

image.png

image.png

然后给 cancelBtn 也加一行 console.log 测试一下。

image.png

效果如下:

c7faaffaa3ca4f709d633b42ed0ae848_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

解决方法简单的出乎你的意料,让我们回到中间的 diaolog 身上,仅仅只需要绑定一个空的 click 函数,然后加上修饰符 stop 即可。

image.png

效果如下,可以看到,现在点击 dialog 已经不会错误的关闭整个 对话框了。

75c2b0668dd144669769c8b347f9e00e_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.jpg

  1. 至此我们的 dialog 组件已经可以在绝大部分场景下使用了。🎁~

总结


目前的代码只是一个很粗糙的实现,更加具体实用的功能还需读者根据自己项目的需求自行完成。下面是 DialogCreator.ts 文件的代码。读者可根据需要自行查阅。

import Dialog from "./Dialog.vue";
import { h, render } from "vue";
interface DialogType {
  title: string;
  content: string;
  confirmBtn: () => void;
}
export interface DialogPropsType extends DialogType {
  closeBtn: () => void;
}
export class DialogCreator {
  containerEl: HTMLDivElement;
  option: DialogPropsType;
  constructor(option: DialogType) {
    this.containerEl = document.createElement("div");
    this.option = { ...option, closeBtn: this.disMiss.bind(this) };
  }
  present() {
    const vnode = h(Dialog, this.option);
    render(vnode, this.containerEl);
    document.body.insertBefore(this.containerEl, document.body.firstChild);
  }
  disMiss() {
    render(null, this.containerEl);
    document.body.removeChild(this.containerEl);
  } //dialog 消失的方法
}


相关文章
|
9天前
vue3【实战】语义化首页布局
vue3【实战】语义化首页布局
28 2
|
9天前
|
存储 容器
vue3【实战】来回拖拽放置图片
vue3【实战】来回拖拽放置图片
19 2
|
9天前
|
JavaScript 开发工具 开发者
vue3【提效】使用 VueUse 高效开发(工具库 @vueuse/core + 新增的组件库 @vueuse/components)
vue3【提效】使用 VueUse 高效开发(工具库 @vueuse/core + 新增的组件库 @vueuse/components)
32 1
|
4天前
【vue3】Argumnt of type ‘history:RouterHistory;}is not assignable to paraeter of type ‘RouterOptions‘.
【vue3】Argumnt of type ‘history:RouterHistory;}is not assignable to paraeter of type ‘RouterOptions‘.
6 0
|
4天前
|
JavaScript
【vue3】vue3中路由hash与History的设置
【vue3】vue3中路由hash与History的设置
9 0
|
4天前
|
编解码 前端开发
【Vue3】解决电脑分辨率125%、150%及缩放导致页面变形的问题
【Vue3】解决电脑分辨率125%、150%及缩放导致页面变形的问题
11 0
|
4天前
|
JavaScript
【vue】 vue 翻页时钟制作,vue2、vue3
【vue】 vue 翻页时钟制作,vue2、vue3
11 0
|
2天前
|
JavaScript
|
4天前
|
JavaScript
【vue】el-dialog 内的tinymce弹窗被遮挡的解决办法 及 tinymce打开弹出菜单后直接关闭对话组件,导致该弹出菜单残留
【vue】el-dialog 内的tinymce弹窗被遮挡的解决办法 及 tinymce打开弹出菜单后直接关闭对话组件,导致该弹出菜单残留
17 6
|
1天前
|
存储 缓存 JavaScript
vue代码优化方案
【7月更文挑战第13天】 **Vue.js 优化要点:** 分解大组件以提高复用性和加载速度;利用计算属性与侦听器优化数据处理;使用Object.freeze()减少响应式数据;借助Vuex或Composition API管理状态;实现虚拟滚动和无限加载提升长列表性能;路由懒加载减少初始加载时间;用Vue DevTools检测性能瓶颈;定期代码审查与重构;应用缓存策略;遵循最佳实践与团队规范,提升应用整体质量。
10 2