目录
概述
该代码定义了一个自定义的 Vue.js 插件,用于在 Vue 应用程序中提供对话框组件 (DialogBox
)。该插件使开发者能够通过全局方法动态创建和管理对话框,便于与用户进行交互和数据处理。
实用性
一个后台管理系统,可能存在很多文件上传弹窗组件、流程审批弹窗等,每次调用这些弹窗时需要在模板上写大量代码(当然,你封装一个通用组件也可以,但是data里面也要写控制弹窗显示隐藏的变量),为了尽可能减少template里面写大量代码以及避免data里面写过多变量(主打一个"懒"),这款对话款组件只需在methods里面定义并配置就行
优点
-
简化对话框管理: 插件通过封装对话框的创建、显示和销毁过程,使得在 Vue 应用程序中使用对话框变得非常简单和直观。
-
全局方法访问: 将
$DialogBox
方法添加到 Vue 原型中,可以在任何 Vue 组件中直接通过this.$DialogBox
调用,不需要显式导入和管理每个对话框的实例。 -
灵活的选项传递:
PromptTip
函数允许传递各种选项来配置对话框的外观和行为,例如标题、内容、按钮文本等,使其适应不同的需求场景。 -
Promise 支持: 对话框的
submit
和cancel
事件通过 Promise 提供异步处理能力,使得能够在用户交互后直接处理结果,如提交表单、执行异步操作等。 -
清理和销毁管理: 插件提供了
destroyDialog
函数来确保对话框在使用后能够被正确清理和销毁,避免内存泄漏和页面元素残留问题。
扩展性
-
组件定制:
DialogBox
组件是可定制的,可以根据具体项目的设计语言和需求进行样式和行为的定制,如添加动画效果、改变布局结构等。 -
事件扩展: 可以在
DialogBox
组件中扩展更多的自定义事件,以支持更复杂的交互逻辑或用户反馈机制,如输入验证、自定义按钮行为等。 -
插件功能扩展: 可以通过扩展插件的
PromptTip
方法,添加额外的功能或参数,以应对更复杂的对话框场景,如多步骤对话框、带有图表或媒体内容的对话框等。 -
跨平台支持: 虽然上述代码基于 Vue.js,但类似的思路和方法也可以用于其他前端框架或纯 JavaScript 应用中,以实现跨平台的对话框管理。
-
状态管理集成: 可以结合 Vuex 或其他状态管理工具,使得对话框的状态和数据更容易在应用中共享和管理,提高代码的可维护性和可扩展性。
插件源码
entry.js(入口文件)
import DialogBox from "./index.vue";
export default {
install: function (Vue) {
let Dialogtructor = Vue.extend(DialogBox); // 继承组件
let instance = null;
const PromptTip = (options = {}) => {
return new Promise((resolve, reject) => {
instance = new Dialogtructor({
// 初始化组件实例
data: {
visible: true,
...options,
},
});
instance.$once("cancel", (data) => {
// 监听弹窗关闭
reject(data);
destroyDialog();
});
instance.$once("submit", (data) => {
// 监听弹窗提交数据
console.log(data, "data");
resolve(data);
destroyDialog();
});
// 销毁弹窗
const destroyDialog = () => {
document.body.removeChild(instance.$mount().$el);
instance && instance.$destroy();
instance = null;
};
document.body.appendChild(instance.$mount().$el);
});
};
Vue.prototype.$DialogBox = PromptTip;
},
};
DialogBox.vue(需要扩展的组件,可扩展,可自定义,这里只是一个示例而已~)
<template>
<el-dialog
:visible="visible"
:title="title"
@close="handleCancel"
append-to-body
custom-class="small-dialog"
:close-on-click-modal="true"
>
<!-- 根据条件加载单个子组件 -->
<component
:is="componentUrl"
:query="query"
ref="child"
v-if="urlArray.length == 1"
></component>
<!-- 根据条件加载多个子组件的选项卡 -->
<el-tabs
v-model="activeName"
:type="tabsType"
v-else-if="urlArray.length > 1"
>
<el-tab-pane
v-for="(item, index) in componentUrlArray"
:label="item.label"
:key="index"
><component :is="item.url" ref="child" :query="query"></component
></el-tab-pane>
</el-tabs>
<!-- 如果urlArray为空,则显示提示信息 -->
<span v-else>请配置子组件路径</span>
<!-- 底部按钮区域 -->
<span slot="footer">
<el-button @click="handleCancel">{{ cancelButtonText }}</el-button>
<el-button @click="handleConfirm" type="primary">{{
confirmButtonText
}}</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
components: { },
data() {
return {
activeName: "0", // 当前激活的选项卡的索引
tabsType: "card", // 选项卡的样式类型
urlArray: [], // 子组件路径数组
query: "", // 传递给子组件的查询参数
confirmButtonText: "确认", // 确认按钮文本
cancelButtonText: "取消", // 取消按钮文本
visible: false, // 对话框可见性
title: "", // 对话框标题
};
},
computed: {
// 计算属性:根据urlArray的第一个元素动态加载单个子组件的路径
componentUrl() {
return require(`@/views/${this.urlArray[0].value}.vue`).default;
},
// 计算属性:根据urlArray中的每个元素动态生成包含label和url的对象数组,用于多个选项卡的子组件加载
componentUrlArray() {
const arr = this.urlArray.map((item) => {
return {
label: item.label,
url: require(`@/views/${item.value}.vue`).default,
};
});
return arr;
},
},
methods: {
// 确认按钮点击事件处理方法,根据子组件的ref获取数据并触发submit事件
handleConfirm() {
const res =
this.$refs.child.length > 1
? this.$refs.child.map((item) => item.$data)
: this.$refs.child.$data;
this.$emit("submit", { res, index: this.activeName });
},
/ 取消按钮点击事件处理方法,关闭对话框并触发cancel事件
handleCancel() {
this.visible = false;
this.$emit("cancel");
},
},
created() {},
};
</script>
<style lang="scss" scoped></style>
该示例主要用于展示一个对话框(el-dialog)组件,可以根据条件动态加载不同的子组件(component),可扩展为文件上传、流程审批组件等
插件注册
main.js
import DialogBoxPlugin from "@/views/tool/package/components/dialogBox/entry.js";
Vue.use(DialogBoxPlugin);
在业务组件中调用
<template>
<div class="title">
<div>一款简化开发的Dialog组件</div>
<el-button type="text" icon="el-icon-view" @click="dialogBox">预览</el-button>
</div>
</template>
<script>
export default {
components: {
},
props: {},
data() {
return {
}
},
watch: {},
computed: {},
methods: {
dialogBox() {
this.$DialogBox({
title: "弹窗标题",
confirmButtonText: "保存",
cancelButtonText: "取消",
query: {
a: 1,
b: 2,
},
urlArray: [
{
label: "MoreButtons组件",
value: "tool/package/components/moreButtons/MoreButtonsDemo",
},
{
label: "CommonCard组件",
value: "tool/package/components/commonCard/CommonCardDemo",
},
],
})
.then((res) => {})
.catch((res) => {});
},
},
created() {},
mounted() {},
};
</script>
调用展示:点击确认会调用插件的handleConfirm方法,获取子组件data里面的值,并且获取当前切换子组件的索引
总结
这个自定义的 Vue.js 插件简化了在 Vue 应用程序中创建和管理对话框的过程。它通过将对话框逻辑封装到插件中,提升了模块化和可重用性以及扩展性,有助于编写更清晰和易于维护的代码。