vue3+TS实战中Dialog弹窗封装复用的技巧

简介: Dialog弹窗在后台管理系统中是使用频率非常高的组件,添加和修改数据基本都会用到,本文就讲讲在vue3和ts的项目中如何封装Dialog组件,实现代码高复用

前言

Dialog弹窗在后台管理系统中是使用频率非常高的组件,添加和修改数据基本都会用到,本文就讲讲在vue3和ts的项目中如何封装Dialog组件,实现代码高复用

在这里插入图片描述

业务要求

如下图,在后台管理系统中需要对数据进行添加和编辑,希望他们能共用一个弹窗,那么我们就需要对弹窗的功能进行封装。下面一起来看看在vue3+ts的项目中如何实现:
在这里插入图片描述

封装步骤

对于Dialog组件的封装,我们大致进行如下步骤实现:

  1. 首先实现Dialog组件的UI部分
  2. 点击按钮给组件传入不同的数据,从而判断是编辑功能还是添加功能
  3. 对于不同的功能,请求不同的接口地址

其中主要的难点在于第二步,涉及组件的传值(defineProps)和组件的自定义事件(emits)。
下面来分布详细介绍:

1.Dialog组件的UI部分实现

我这里使用的是element-plus。
首先在components文件夹下新建文件DialogModal.vue 用来写这个组件
UI部分没什么难点,我这里直接贴代码了,根据自己需求进行修改:

<template>
  <el-dialog
    :before-close="handleClose"
    v-model="show"
    :title="editData ? '编辑收支信息' : '添加收支信息'"
  >
    <el-form
      :model="formData"
      ref="form"
      :rules="formRules"
      label-width="120px"
      style="margin: 10px; width: auto"
    >
      <el-form-item label="收支类型">
        <el-select v-model="formData.type" placeholder="收支类型">
          <el-option
            v-for="(formType, index) in typeList"
            :key="index"
            :label="formType"
            :value="formType"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="describe" label="收支描述">
        <el-input v-model="formData.describe" type="describe"></el-input>
      </el-form-item>
      <el-form-item prop="income" label="收入">
        <el-input v-model="formData.income" type="income"></el-input>
      </el-form-item>
      <el-form-item prop="expend" label="支出">
        <el-input v-model="formData.expend" type="expend"></el-input>
      </el-form-item>
      <el-form-item prop="cash" label="账户现金">
        <el-input v-model="formData.cash" type="cash"></el-input>
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="formData.remark" type="textarea"></el-input>
      </el-form-item>
      <el-form-item class="text-right">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSubmit(form)">提交</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

有不懂的变量别着急,下面会讲

2.组件传值和自定义事件

这里我们按功能分块来讲:

编辑功能

首先我们在list页面,

  1. 定义show控制弹窗组件的显示,定义editData存放修改的数据
const show = ref<boolean>(false);
const editData = ref<formDataType>()

这里editData是自定有类型formDataType,从外部ts中引入的类型:

import { formDataType} from "../utils/types";

贴一下这个ts文件的代码:

export interface formDataType {
    type: string;
    describe: string;
    income: string;
    expend: string;
    cash: string;
    remark: string;
    _id?: string;
}
  1. 然后给编辑按钮绑定@click="handleEdit(scope.row),然后写这个点击事件:

控制弹窗显示,然后将点击的当前行数据赋值给 editData

const handleEdit = (row: formDataType) => {
  show.value = true;
  editData.value = row;
};
  1. 在DialogModal组件上绑定传值 show和ditData
<DialogModal
    :show="show"
    :editData="editData"
/>

4.回到DialogModal组件的页面,下面我们要接收传值和监听数据
这是使用defineProps接受传值:

const props = defineProps({
  show: {
    type: Boolean,
  },
  editData: {
    type: Object as () => formDataType,
  },
});

我们点击编辑,编辑的弹窗需要显示当前行的数据,所以需要监听传过来的editData,将它赋值给弹窗中的form表单:
因为props是对象,要监听对象中的数据,所以在watch中使用下面的写法

watch(
  () => props.editData,
  () => {
    formData.value = props.editData;
  }
);

只有点击编辑按钮,才会传入editData 数据,所以可以通过editData 控制弹窗的title

<el-dialog
    :before-close="handleClose"
    v-model="show"
    :title="editData ? '编辑收支信息' : '添加收支信息'"
  >

添加功能和自定义事件

  1. 还是先来到list页面来写添加功能,对于添加功能的点击事件,不需要传数据,只用控制弹窗显示
const handleAdd = () => {
  show.value = true;
};
  1. 下面我们要实现弹窗关闭的时候的操作,就需要用到自定义事件:

第一个是@closeModal事件,只需要控制弹窗的show为false关闭弹窗
第二个是 @handleUpdateProfiles事件,这个事件中需要调用getProfiles();方法

<DialogModal
    :show="show"
    @closeModal="show = false"
    @handleUpdateProfiles="handleUpdateProfiles"
    :editData="editData"
  />

getProfiles()方法就是从新获取表格的数据,用于修改或者添加操作完成后刷新数据

const handleUpdateProfiles = () => {
  getProfiles();
};
  1. 来到DialogModal组建的页面,使用emits处理上面写的自定义事件
const emits = defineEmits(["closeModal", "handleUpdateProfiles"]);

然后需要添加一个dialog的:before-close="handleClose"事件,在关闭弹窗的时候触发事件
也就是触发自定义的closeModal事件

const handleClose = () => {
  formData.value = {}
  emits("closeModal");
};

3.不同功能进行不同的api地址请求

  1. 在请求之前,肯定要进行表单的验证:
const formRules: formRulesType = {
  describe: [{ required: true, message: "收支描述不能为空", trigger: "blur" }],
  income: [{ required: true, message: "收入不能为空", trigger: "blur" }],
  expend: [{ required: true, message: "支出不能为空", trigger: "blur" }],
  cash: [{ required: true, message: "账户现金不能为空", trigger: "blur" }],
};

formRulesType类型也是由自己写的ts文件引入,贴上代码(跟上面使用过的同一文件):

export interface formRulesType {
    describe: {
        required: boolean;
        message: string;
        trigger: string;
    }[];
    income: {
        required: boolean;
        message: string;
        trigger: string;
    }[];
    expend: {
        required: boolean;
        message: string;
        trigger: string;
    }[];
    cash: {
        required: boolean;
        message: string;
        trigger: string;
    }[];
}

如果表单验证正确,我们就可以进行请求了:
表单验证的逻辑就不多说了,看重要的url部分,如果props.editData存在,url则为edit/${props.editData._id},不存在则为add。所以后面进行post请求的地址就是/api/profiles/加上url的内容。
请求完成之后调用自定义事件handleUpdateProfiles和handleUpdateProfiles。刷新表格数据和关闭弹窗

const handleSubmit = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate(async (valid: boolean) => {
    if (valid) {
      const url = props.editData?._id ? `edit/${props.editData._id}` : "add";
      await axios.post(`/api/profiles/${url}`, formData.value);
      // @ts-ignore
      ElMessage.success("保存成功");
      emits("handleUpdateProfiles");
      emits("handleUpdateProfiles");
    } else {
    }
  });
};

最后

到这里我们就完成了整个Dialog弹窗组件的封装,核心就在于通过传值判断是编辑还是添加操作,再通过不同的操作完成不同api的请求。

在前端开发中创建自定义组件是必不可少的一项基本技能,理解这样的封装思想在实际开发中是很有必要的,可以提高代码重复利用性,减少代码量。

有疑问欢迎留言交流,批评指正。创作不易,如果对你有帮助 请点赞关注支持下~
后续会给大家带来更多的优质内容。感谢支持!!!

相关文章
|
8月前
|
人工智能 自然语言处理 JavaScript
通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
通义灵码基于自然语言需求,快速生成完整Vue组件。例如,用Vue 2和JavaScript实现贪吃蛇游戏:包含键盘控制、得分系统、游戏结束判定与Canvas动态渲染。AI生成的代码符合规范,支持响应式数据与事件监听,还能进阶优化(如增加启停按钮、速度随分数提升)。传统需1小时的工作量,使用通义灵码仅10分钟完成,大幅提升开发效率。操作简单:安装插件、输入需求、运行项目即可实现功能。
450 4
 通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
|
8月前
|
JavaScript API 容器
Vue 3 中的 nextTick 使用详解与实战案例
Vue 3 中的 nextTick 使用详解与实战案例 在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。
776 17
|
9月前
|
存储 JavaScript 前端开发
基于 ant-design-vue 和 Vue 3 封装的功能强大的表格组件
VTable 是一个基于 ant-design-vue 和 Vue 3 的多功能表格组件,支持列自定义、排序、本地化存储、行选择等功能。它继承了 Ant-Design-Vue Table 的所有特性并加以扩展,提供开箱即用的高性能体验。示例包括基础表格、可选择表格和自定义列渲染等。
816 6
|
JavaScript UED
"Vue实战技巧大揭秘:一招解决路由跳转页面不回顶部难题,让你的单页面应用用户体验飙升!"
【10月更文挑战第23天】在Vue单页面应用中,点击路由跳转时,默认情况下页面不会自动滚动到顶部,这可能影响用户体验。本文通过一个新闻网站的案例,介绍了如何使用Vue-router的全局前置守卫和`scrollBehavior`方法,实现路由跳转时页面自动滚动到顶部的功能,提升用户浏览体验。
611 0
|
4月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
418 2
|
3月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
372 137
|
7月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
903 0
|
7月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
8月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
1121 78
|
6月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
537 1