Vue中封装制作一个可复用的模态框组件

简介: Vue中封装制作一个可复用的模态框组件

在浏览网页的过程中,模态框其实并不陌生。

不过在vue开发过程中,应当如何封装一个vue组件为可以复用的模态框呢?

1,思路

首先我们不难发现,模态框有以下特点:

  • 有一个半透明蒙层,防止用户没有做完模态框的命令就操作其它内容
  • 显示在最顶层,这说明很多模态框是直接放在body元素中的

我先开始就想,能不能先在vue文件中把模态框样式定义好,然后利用props或者slot传值、利用refs调用其方法呢?后来发现这样不仅不方便(每次都要注册组件)、还无法把模态框直接放在body里面。

参考了官方文档,我发现其实再写一个配套的js文件,在js文件中定义显示模态框的函数,借助这个js在body元素下创建一个元素,并将vue组件挂载上去即可。下面我们就一一来实现。

2,编写vue文件,完成模态框基本样式

首先需要完成一些对话框的基本样式,我在components目录下创建vue文件,内容如下:

<template><divclass="mydialog"><divclass="frame"><divclass="content"><img:src="image"/><divclass="text">{{ text }}</div></div><divclass="buttons"><divclass="ok"@click="clickOk">确定</div><divclass="cancel"@click="clickCancel">取消</div></div></div></div></template><script>exportdefault {
name: 'mydialog',
data() {
return {
/**       * 显示文字       */text: '',
/**       * 显示图片       */image: '',
/**       * 模态框挂载的DOM元素,用于后面销毁模态框       */mountDom: '',
    };
  },
methods: {
/**     * 自定义确定事件     */ok() {},
/**     * 自定义取消事件     */cancel() {},
clickOk() {
// 先执行自定义确定方法this.ok();
// js传入该模态框实例挂载的元素,关闭时将其销毁this.mountDom.remove();
    },
clickCancel() {
// 先执行自定义取消方法this.cancel();
// js传入该模态框实例挂载的元素,关闭时将其销毁this.mountDom.remove();
    },
  },
};
</script><stylelang="scss"scoped>.mydialog {
position: absolute;
width: 100vw;
height: 100vh;
left: 0;
top: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.7);
.frame {
width: 560px;
height: 250px;
background-color: rgb(177, 255, 229);
box-shadow: 1px1px7px2pxrgb(90, 203, 255);
border-radius: 5px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
.content {
display: flex;
width: 85%;
justify-content: flex-start;
align-items: center;
img {
height: 64px;
      }
.text {
font-size: 24px;
margin-left: 24px;
      }
    }
.buttons {
display: flex;
width: 80%;
justify-content: space-around;
align-items: center;
font-size: 26px;
.ok,
.cancel {
width: 75px;
height: 32px;
text-align: center;
line-height: 32px;
border-radius: 6px;
user-select: none;
cursor: pointer;
      }
.ok {
        &:hover {
color: white;
background-color: blue;
        }
      }
.cancel {
        &:hover {
color: white;
background-color: rgb(255, 0, 98);
        }
      }
    }
  }
}
</style>

这里重点是在data()中我定义了一些变量,用于我们可以自定义模态框内容。

问题是,模态框这么销毁自己呢?就算是使用v-if关闭了自己,但是前面提到了,这个模态框是要挂载至一个元素中的,这个挂在元素无法被消除怎么做呢?

所以可以看到上面还有一个mountDom变量,让js创建挂载元素之后将其传入,这样vue就可以直接销毁这个挂载元素了!

除此之外,还预留了okcancel两个函数用于按下“确定”和“取消”之后的自定义事件,传入自定义的函数赋值给okcancel即可。

3,编写js文件,封装方法以供调用,给模态框组件传参

在同级目录下创建js文件,内容如下:

import {
createApp} from'vue';
importMyDialogfrom'./MyDialog.vue';
/** * 显示自定义对话框 * @param {String} text 对话框提示内容  * @param {NodeRequire} image 对话框图标(需要require图片路径) * @param {Function} ok 自定义确定事件 * @param {Function} cancel 自定义取消事件 */exportfunctionshowDialog(text, image, ok, cancel) {
// 创建一个div元素放到body下面,供模态框vue组件挂载letmountDom=document.createElement('div');
mountDom.style.position='absolute';
mountDom.style.left=0;
mountDom.style.top=0;
document.body.appendChild(mountDom);
// 挂载组件以显示,mount函数返回vue组件实例letdialog=createApp(MyDialog).mount(mountDom);
// 设定vue实例中的变量,将一些数据传入vuedialog.text=text;
dialog.image=image;
dialog.ok=ok;
dialog.cancel=cancel;
// 传入挂载的dom是为了vue组件关闭时可以直接销毁这个挂载的dom达到销毁模态框的目的dialog.mountDom=mountDom;
}

可见这里就很简单了。定义一个函数,先创建一个div元素加到body中用于挂载对话框组件,然后利用createApp函数挂载这个对话框组件至创建的div元素之下即可。

看到这,大家也知道了怎么在js中,向vue实例传递值或者调用函数了。

在官方文档中,对于createApp函数,有这样一句话:

与大多数应用方法不同的是,mount不返回应用本身。相反,它返回的是根组件实例。

网络异常,图片无法展示
|

我们知道,每一个vue组件可以被作为一个实例使用,那么mount函数,不仅仅是挂载了组件至指定的元素下,还会返回其实例,我们也可以调用这个实例中的变量、函数,实现传递参数的目的。

mount函数中,可以是dom元素实例,也可以是字符串形式的选择器(例如'#app',挂载到id为app的元素下)。

4,测试

现在我们在根组件里面写一个按钮并调用试试:

<template><divclass="app"><button@click="testShowDialog">显示模态框</button></div></template><script>// 先引入js中显示对话框函数import { showDialog } from'./components/mydialog.js';
exportdefault {
name: 'app',
methods: {
testShowDialog() {
showDialog(
'提示:少时诵诗书所所所所所所所所所所所所所所所所所所所所所所所所所所所所所所所',
require('./assets/1.png'),
        () => {
console.log('点击了确定');
        },
        () => {
console.log('点击了取消');
        }
      );
    },
  },
};
</script>

效果:

网络异常,图片无法展示
|

我们来看看html中元素:

网络异常,图片无法展示
|

再结合一下上面的js文件看看,相信能够理解这个思路。

5,总结

可见封装一个可复用的vue组件并不难,先写好样式,再写一个配套的js文件给其传参、用于调用即可。其实封装其它类型可复用组件,也是一样的思路。

示例代码仓库地址

相关文章
|
8月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
728 2
|
11月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
1159 0
|
11月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
11月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
770 1
|
存储 前端开发 JavaScript
为什么我不再用Vue,改用React?
当我走进现代前端开发行业的时候,我做了一个每位开发人员都要做的决策:选择一个合适的框架。当时正逢 jQuery 被淘汰,前端开发者们不再用它编写难看的、非结构化的老式 JavaScript 程序了。
|
7月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
614 137
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1451 4
|
12月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
1671 78
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
10月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
731 1