DialogBox组件(自定义对话框插件)

目录

概述

实用性

优点

扩展性

 插件源码

插件注册

 在业务组件中调用

 总结


概述

        该代码定义了一个自定义的 Vue.js 插件,用于在 Vue 应用程序中提供对话框组件 (DialogBox)。该插件使开发者能够通过全局方法动态创建和管理对话框,便于与用户进行交互和数据处理。

实用性

        一个后台管理系统,可能存在很多文件上传弹窗组件、流程审批弹窗等,每次调用这些弹窗时需要在模板上写大量代码(当然,你封装一个通用组件也可以,但是data里面也要写控制弹窗显示隐藏的变量),为了尽可能减少template里面写大量代码以及避免data里面写过多变量(主打一个"懒"),这款对话款组件只需在methods里面定义并配置就行

优点
  1. 简化对话框管理: 插件通过封装对话框的创建、显示和销毁过程,使得在 Vue 应用程序中使用对话框变得非常简单和直观。

  2. 全局方法访问:$DialogBox 方法添加到 Vue 原型中,可以在任何 Vue 组件中直接通过 this.$DialogBox 调用,不需要显式导入和管理每个对话框的实例。

  3. 灵活的选项传递: PromptTip 函数允许传递各种选项来配置对话框的外观和行为,例如标题、内容、按钮文本等,使其适应不同的需求场景。

  4. Promise 支持: 对话框的 submitcancel 事件通过 Promise 提供异步处理能力,使得能够在用户交互后直接处理结果,如提交表单、执行异步操作等。

  5. 清理和销毁管理: 插件提供了 destroyDialog 函数来确保对话框在使用后能够被正确清理和销毁,避免内存泄漏和页面元素残留问题。

扩展性

  1. 组件定制: DialogBox 组件是可定制的,可以根据具体项目的设计语言和需求进行样式和行为的定制,如添加动画效果、改变布局结构等。

  2. 事件扩展: 可以在 DialogBox 组件中扩展更多的自定义事件,以支持更复杂的交互逻辑或用户反馈机制,如输入验证、自定义按钮行为等。

  3. 插件功能扩展: 可以通过扩展插件的 PromptTip 方法,添加额外的功能或参数,以应对更复杂的对话框场景,如多步骤对话框、带有图表或媒体内容的对话框等。

  4. 跨平台支持: 虽然上述代码基于 Vue.js,但类似的思路和方法也可以用于其他前端框架或纯 JavaScript 应用中,以实现跨平台的对话框管理。

  5. 状态管理集成: 可以结合 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 应用程序中创建和管理对话框的过程。它通过将对话框逻辑封装到插件中,提升了模块化和可重用性以及扩展性,有助于编写更清晰和易于维护的代码。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端摸鱼侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值