前言:
我们在写vue项目时,弹框是非常常用的组件,并且在同一个项目中,弹框大多类似。所以我们可以抽离封装出一个通用的弹框;
因为vue3可向下兼容,所以作者这边会使用vue2的写法,vue3写法大同小异。
第一步:新建相关文件
一般来说是在src/components/dialog下新建如下两个文件:
- index.vue:该文件是组件内容相关的,用来书写弹框组件的结构、样式、和动态逻辑;
- index.js:该文件使用虚拟节点创建组件内容,并且注册组件。
第二步:书写组件内容
index.vue组件内容如下:
- 结构 + js 代码
<template> <div class="default-message" :id="boxId"> <div class="default-message-content"> <div class="default-message-title">{{ title }}</div> <div class="default-message-value" v-html="message"></div> <div class="default-message-btns"> <div class="default-message-cancle default-message-btn" v-if="cancelBtnHtml" @click.prevent.stop="handleCancel" > {{ cancelBtnHtml }} </div> <div class="default-message-submit default-message-btn" @click.prevent.stop="handleOk" > {{ okBtnHtml }} </div> </div> </div> </div> </template> <script> import i18n from "@/i18n"; import { defineComponent } from "vue"; export default defineComponent({ name: "Dialog", data() { return { i18nTitle: '', i18nOkBtn: '', }; }, props: { boxId: { type: String, default: "", }, // 标题 title: { type: String, default: "", }, // 内容 message: { type: String, default: "", }, // 确定按钮文字 okBtnHtml: { type: String, default: '', }, // 取消按钮文字 cancelBtnHtml: { type: String, default: "", }, // 成功回调 ok_function: { type: Function, }, // 失败回调 cancel_function: { type: Function, }, }, methods: { handleCancel() { this.removeModal(); this.cancel_function && this.cancel_function(); }, handleOk() { this.removeModal(); this.ok_function && this.ok_function(); }, removeModal() { const modelDom = document.getElementById( "__default__container__content__" ); if (modelDom) { document.body.removeChild(modelDom); } }, }, created() { this.i18nTitle = i18n.global.t('modal_warm_tip_title'); this.i18nOkBtn = i18n.global.t('activity_ok'); }, }); </script>
结构说明:
.default-message使我们整个弹框的容器,一般宽高都设置为100%,这个部分会有一个半透明的背景色(覆盖页面内容,防止弹框了还能操作页面);.default-message-content为整个弹框的内容区域,包括标题、提示信息、取消按钮、确定按钮;- 取消按钮和确定按钮支持执行传入的事件,方便我们在弹框弹出后点击按钮执行相应操作;
- 样式
<style lang="less" scoped> .default-message { position: fixed; right: 0; top: 0; bottom: 0; left: 0; width: 100%; height: 100%; z-index: 1000; background: rgba(0, 0, 0, 0.7); .default-message-title { color: #333; margin: 0; line-height: 1.5; font-size: 18px; min-height: 18px; padding-top: 20px; text-overflow: ellipsis; font-weight: bold; cursor: move; text-align: center; } .default-message-content { width: 85%; position: absolute; top: 50%; left: 50%; transform: translate3d(-50%, -50%, 0); background-color: #fff; border-radius: 6px; transition: all 0.2s ease-in; color: #999; font-size: 18px; } .default-message-value { padding: 28px 18px; text-align: center; position: relative; color: #999; text-align: center; font-size: 14px; color: rgba(102, 102, 102, 1); } .default-message-btns { // border-top: 1px solid #ddd; display: flex; height: 60px; position: relative; &:after { position: absolute; content: ""; display: inline-block; left: 0; right: 0; top: 0; height: 1px; transform: scaleY(0.5); background: #ddd; } .default-message-btn { flex: 1; display: flex; align-items: center; justify-content: center; font-size: 16px; padding: 0 3px; } .default-message-submit { color: #26a2ff; } .default-message-cancle { color: #999; position: relative; &:after { position: absolute; content: ""; display: inline-block; top: 0; right: 0; bottom: 0; width: 1px; transform: scaleX(0.5); background: #ddd; } } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } } </style>
第三步:注册成全局组件
import {createVNode, render} from 'vue'; import MessageConstructor from './index.vue'; const $dialog = function (options) { // 已存在一个弹窗则不重复渲染 if (!document.getElementById ('__default__container__content__')) { // 创建div const container = document.createElement ('div'); // container.className = `__default__container__message__`; container.id = '__default__container__content__'; //创建虚拟节点 const vm = createVNode (MessageConstructor, options); //渲染虚拟节点 render (vm, container); document.body.appendChild (container); } }; export default { //组件注册 install (app) { app.config.globalProperties.$dialog = $dialog; }, };
到这里,我们的弹框组件就完成了,接下来我们来使用看看。
项目中使用弹框
使用的方法也非常简单,所见即所得。
app.config.globalProperties.$dialog({ title: "弹框标题", message: "弹框提示信息文案", okBtnHtml: "确定", cancelBtnHtml: "取消", ok_function: () => { console.log("点击弹框确定按钮处理函数"); }, cancel_function: () => { console.log("点击弹框取消按钮处理函数"); } });
说明:
- 标题、提示文案、以及取消和确定按钮文案,我们这边直接传入,
ok_function是确定按钮的回调,我们可以在这里做任何点击确定后想做的事,包括发送请求和异步操作,cancel_function同理。 - 弹框图片示例:

写在后面
这是一个比较基础的弹框组件,这边示例的代码是比较全的,对细节要求不大的小伙伴可以直接用;
背景颜色、字体、布局等这些细节,因为每个业务场景不同,大家可以根据自己的需要适当调整;
弹框是固定单位的,如果小伙伴的项目需要使用响应式大小,直接对应替换大小单位即可;
对你有帮助的话给作者点点关注吧,你的支持是我不断更新的动力!Peace and love~~