el-dialog 关闭再打开后窗口内容不刷新问题

news2024/11/19 1:30:00

页面中有增加和编辑两个功能,由于弹窗样式都是一样的,于是将它拆分成一个子组件,父组件把状态传给子组件,子组件根据这个状态判断是做编辑操作还是新增操作.

编辑

 

添加

 

 

问题一:但是这样遇到了一个问题,在编辑时,只有第一次点编辑时,回显的数据才能正确显示。随后再点其他部门的编辑,数据显示不正确了,还是第一次点开的那个部门的数据.

原因:现在的代码中,获取部门详情这个动作在子组件的created中发出的,而created钩子只会执行一次:后续点击关闭弹层时,子组件被没有销毁,它只是隐藏了。

问题二:点击编辑之后再点击添加,添加表单中也会出现部门详情数据

原因是关闭弹窗时,子组件被没有销毁,它只是隐藏了,也没有清空里面表单的数据

我们先来看问题一数据不更新

问题一:回显数据不更新

解决方案一:在父组件中,给父组件中的el-dialog添加destroy-on-close属性

查阅了 Dialog 对话框 相关文档:

 我们可以给它加上这个属性

<el-dialog
        :title="isEdit?'编辑':'新增'"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        @close="resetForm"
      >
        <!-- element ui 中dialog的方法destroy-on-close,关闭时销毁 Dialog 中的元素 -->
        <deptDialog
          :id="fatherId"
          :origin-list="originList"
          :is-edit="isEdit"
          destroy-on-close
          @success="doSuccess"
          @doClose="dialogVisible=false"
        />
      </el-dialog>

解决方案二:直接在内容上加上属性 v-if="dialogVisible"

v-if="dialogVisible",关闭和打开弹层,销毁和创建组件

v-if会由false=>true,会触发beforeCreate,created,beforeMount,mounted 钩子。

由true=>false,会触发 beforeDestroy,destroyed 钩子。

所以我们只要给它加上v-if,取值为控制弹窗显示隐藏的值,我们打开弹窗时它就会重新重建,关闭弹窗的话就会销毁,

这样每次打开弹窗都会执行created钩子里的获取部门详情函数,问题就解决了

这样做虽然简单,但是它会有性能消耗,其中的ajax请求也会随着组件的创建和销毁重复执行

 

<el-dialog
        :title="isEdit?'编辑':'新增'"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        @close="resetForm"
      >
        <!-- 解决数据不更新的问题:v-if="dialogVisible",关闭和打开弹层,销毁和创建组件 -->
        <deptDialog
          v-if="dialogVisible"
          :id="fatherId"
          :origin-list="originList"
          :is-edit="isEdit"
          @success="doSuccess"
          @doClose="dialogVisible=false"
        />
      </el-dialog>

解决方案三:在父组件中通过引用找到子组件

在父组件中,每次打开弹层时,找到子组件,要求它去发请求获取详情

添加ref引用:

<el-dialog
        :title="isEdit?'编辑':'新增'"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        @close="resetForm"
      >
        <!-- 添加引用: ref="deptDialog" -->
        <deptDialog
          :id="fatherId"
          ref="deptDialog"
          :origin-list="originList"
          :is-edit="isEdit"
          @success="doSuccess"
          @doClose="dialogVisible=false"
        />
      </el-dialog>

 在编辑时:找到子组件,要求它去发请求获取详情

// 编辑
    doEdit(id) {
      //isEdit设为true,表示当前状态为编辑
      this.isEdit = true
      this.fatherId = id
      this.dialogVisible = true
      // 解决数据不更新的问题: this.$refs.deptDialog.loadDepartDetail()
      // 注意:由于DOM更新是异步的,此处要用$nextTick()
      this.$nextTick(() => {
        this.$refs.deptDialog.loadDepartDetail()
      })
      //或者放在宏任务里,如延时器中
      // setTimeout(() => {
      // this.$refs.deptDialog.loadDepartDetail()
      // }, 0)
    },

子组件: 

created() {
    //加载部门负责人列表数据
    this.loadEmployeesSimples()
    //如果为编辑状态,获取部门详情
    if (this.isEdit) this.loadDepartDetail()
  },

解决方案四:在子组件内监听id的变化(不推荐使用)

在子组件内部添加一个侦听器:监听当前id的变化

created() {
    //加载部门负责人列表数据
    this.loadEmployeesSimples()
    //如果为编辑状态,获取部门详情
    if (this.isEdit) this.loadDepartDetail()
  },
watch: {
    id: function(newVal, oldVal) {
      //调用获取部门详情函数
      this.loadDepartDetail()
    }
  }, 
  //上面这种写法不会立即触发,还需在created()中调用一次,用下面这种方法就不需要在created()中调用了
  //watch: {
  //   id: {
  //     handler: function(newVal, oldVal) {
  //       this.loadDepartDetail()
  //     },
  //     immediate: true 
  //   }
  // },
  //immediate表示在watch中首次绑定的时候,是否执行handler,值为true则表示在watch中声明的时候,就立即   //执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。所以当为     //true时 在created周期里就可以不用在写 已经在watch 中写过的方法了

但是这种方法在清空表单数据的时候会有一个bug,不推荐使用,后面会详细讲到.

解决方案五:给子组件添加key值

key就是给每一个vnode的唯一id,可以依靠key更准确地拿到oldVnode中对应的节点。避免组件“原地复用”带来的副作用,加上key,可以让组件在数据变化时强制更新组件。

<el-dialog
        :title="isEdit?'编辑':'新增'"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        @close="resetForm"
      >
        <!-- 给子组件添加key值 -->
        <deptDialog
          :id="fatherId"
          :key="fatherId"
          :origin-list="originList"
          :is-edit="isEdit"
          @success="doSuccess"
          @doClose="dialogVisible=false"
        />
      </el-dialog>

 

问题二:添加表单中也会出现部门详情数据

还是上面说到的问题,关闭弹层时,子组件被没有销毁,它只是隐藏了,所以我们需要手动清除表单中的数据.

(方案一添加destroy-on-close属性,方案二v-if="dialogVisible",方案五给子组件添加key值,不会出现这个问题)

分析:有如下三个操作都需要我们去重置表单

  1. 取消
  2. 确定
  3. 用户直接点击关闭

所以我们可以在Dialog的@close的回调中写一次代码就行了

父组件:

// 给父组件添加 @close="resetForm"
 <el-dialog
        :title="isEdit?'编辑':'新增'"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        @close="resetForm"
      >
      //给子组件添加  ref="deptDialog"
        <deptDialog
          v-if="dialogVisible"
          ref="deptDialog"
          :origin-list="originList"
          :is-edit="isEdit"
          @success="doSuccess"
          @doClose="dialogVisible=false"
        />
      </el-dialog>
// 重置子组件表单
    resetForm() {
      // 调用子组件中的重置表单方法
      this.$refs.deptDialog.resetForm()
    }

子组件:

// 在父组件中 dialog close时,来调用
    resetForm() {
      // resetFields是element-ui中的el-form组件提供一个api,它的作用是:
      // 1. 重置表单数据
      // 2. 清空校验结果(页面上红色的提示)
     this.$refs.deptForm.resetFields()
    }

清空表单数据的bug

问题重现

  1. 选中a部门,进行编辑,故意让编辑出错,在表单上出现错误
  2. 点击取消
  3. 再次对a部门进行编辑,发现数据没有显示出来

原因分析

上面的操作中,前后两次编辑的是同一个部门,所以子组件内对id的watch并没有执行,导致内容为空

所以不推荐使用方案四,对id进行侦听

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/563035.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大学生就业工资低,想转行IT?0基础培训班学习半年云计算出来可以就业吗?挑战高薪职业!

大学生就业工资低&#xff0c;想转行IT&#xff1f;0基础学习云计算可以就业吗&#xff1f; 大学生就业工资低&#xff0c;想转行IT&#xff1f;0基础培训班学习半年云计算出来可以就业吗&#xff1f;这是一个很常见的问题&#xff0c;也是很多大学毕业生关心的话题。根据我了解…

探索2023年海外网红营销合作方式:提升品牌曝光度的创新策略

随着社交媒体的崛起和用户对网红的追捧&#xff0c;海外网红营销已经成为品牌推广的不可忽视的一部分。在2023年&#xff0c;有7种最火爆的海外网红营销合作方式备受瞩目。本文Nox聚星将和大家一起来详细了解这7种方式&#xff0c;为品牌提供更多营销灵感和策略。 1、跨平台合作…

Codeforces Round 834 (Div. 3)

题集链接 Codeforces Round 834 A. Yes-Yes?B. Lost PermutationC. Thermostat A. Yes-Yes? Example input 12 YES esYes codeforces es se YesY esYesYesYesYesYesYe seY Yess sY o Yesoutput NO YES NO YES NO YES YES NO NO YES NO YES题意&题解&#xff1a; 其实就…

Windows环境下安装及部署Nginx教程(含多个站点部署)

目录 一、下载安装Nginx 二、部署Nginx 三、多站点部署的情况 1、nginx域名解析&#xff0c;虚拟主机&#xff1a; 四、带https的站点如何部署&#xff0c;与http的有何不同点&#xff1f; 一、下载安装Nginx 1、官网下载地址&#xff1a;https://nginx.org/en/download.h…

2022 年第四届河南省 CCPC 大学生程序设计竞赛vp补题

Dashboard - 2022 CCPC Henan Provincial Collegiate Programming Contest - Codeforces Problem B. Hash 思路&#xff1a; 发现31的次幂取模的答案&#xff0c;所以如果一段太长肯定不如拆成2段。首先如果一段长度为7,那么无论他的开头是a,eh,n的谁,都有val>31^6887503…

0基础学习VR全景平台篇第29章:场景功能-音乐解说

本期为大家带来蛙色VR平台&#xff0c;场景管理模块-音乐功能&#xff01; 功能位置示意 一、本功能将用在哪里&#xff1f; 优秀VR全景作品不仅注重视觉的体验&#xff0c;接入契合场景的背景音乐与解说&#xff1b; 可将音乐与解说进行全局播放或进行分场景播放&#xff0…

前端学习--Vue(4) 生命周期

一、组件的生命周期 一个组件从创建-运行-销毁的真个阶段&#xff0c;强调的是一个时间段 1.1 生命周期函数 1.1.1 创建 &#xff08;只执行一次&#xff09; created() 阶段任务&#xff1a;最早可以使用methods中的方法发起ajax请求获取数据&#xff0c;并将数据挂载到d…

论文阅读笔记(三)——有监督解耦+信息瓶颈

论文信息 《Disentangled Information Bottleneck》 论文地址&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/17120 代码地址&#xff1a;GitHub - PanZiqiAI/disentangled-information-bottleneck inproceedings{pan2021disentangled, title{Disentangled in…

vue3与vue2共存环境搭建

1、全局安装vue2 npm install vue-cli -g2、自行在任意位置创建一个文件夹&#xff0c;局部安装vue3 npm初始化 npm initnpm初始化 提示&#xff1a; 初始化后 出现文件package.json 如果没有初始化 会报错&#xff0c;且文件夹中不会新增内容 3、局部安装vue3 npm install …

一名优秀的黑客,具备的有哪些特质

想要成为网络hacker黑客&#xff1f;十个必会的特质 一、基本的计算机知识 把它列为第一条&#xff0c;相信很多人肯定会觉得不以为然&#xff0c;其实掌握必要的计算机知识对黑客入门非常重要。这些包括&#xff1a;计算机硬件的组成、操作系统的安装、Windows批处理命令、命…

LeetCode_DFS_困难_1377.T 秒后青蛙的位置

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一棵由 n 个顶点组成的无向树&#xff0c;顶点编号从 1 到 n。青蛙从 顶点 1 开始起跳。规则如下&#xff1a; 在一秒内&#xff0c;青蛙从它所在的当前顶点跳到另一个未访问过的顶点&#xff08;如果它…

apt remove purge的区别 删除包的同时删除配置文件

1、apt remove purge的区别 查看 man apt apt remove&#xff1a;删除软件包&#xff0c;不删除配置文件。这么做的目的是将来再次安装这个包时 原来的配置文件会自动加载供使用。也可以避免误删除包&#xff0c;配置文件还在的话&#xff0c;重新安装一次软件包就可以恢复到…

亚马逊云科技出海日6月9日盛夏盛启

向全球价值链上游奋进 中国企业增强国际竞争力的关键&#xff0c;是努力朝全球价值链上游奋进&#xff0c;发力技术出海。中国的出海新机遇&#xff0c;背后曾是疫情在全球按下数字互联和数字化升级的快进键&#xff0c;跨境电商、在线社交、移动支付、数字服务等数字经济迎来…

Spring 学习总结(37)—— 了解什么是单体的模块化,Spring Modulith 入门实践

1、介绍 模块化单体是一种架构风格,代码是根据模块的概念构成的。 对于许多组织而言,模块化单体可能是一个很好的选择。 它有助于保持一定程度的独立性,这有助于我们在需要的时候轻松过渡到微服务架构。Spring Modulith 是 Spring 的一个实验项目,可用于构建模块化单体应用…

《消息队列高手课》课程笔记(一)

消息生态系统全景图 为什么需要消息队列&#xff1f; 异步处理 大多数程序员在面试中&#xff0c;应该都问过或被问过一个经典却没有标准答案的问题&#xff1a;如何设计一个秒杀系统&#xff1f; 这个问题可以有一百个版本的合理答案&#xff0c;但大多数答案中都离不开消息…

马蹄集oj赛(第五次)

目录 围栏木桩 某农场有一个由按编号排列的根木桩构成的首尾不相连的围栏。现要在这个围栏中选取一些木桩&#xff0c;按照原有的编号次序排列之后&#xff0c;这些木桩高度成一个升序序列。 大厨小码哥 附庸的附庸 最长子段和 旅费 纸带 暧昧团 上楼梯 上楼梯2 采蜜 围栏…

Spring 学习总结(36)—— Spring 状态机优雅实践

1、什么是状态机 1.1 什么是状态 先来解释什么是“状态”( State )。现实事物是有不同状态的,例如一个自动门,就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如自动门的状态就是两个 open 和 closed 。 状…

Mybatisplus真实高效批量插入附容错机制

文章目录 概要优化技术细节小结 概要 提示&#xff1a;mybatisplus自带真实批量插入 在mybatisplus已知常用批量插入为继承Iservice里的saveBatch方法和saveOrUpdateBatch方法&#xff0c; 进入源码可知&#xff0c;此两种方法的插入均为单条插入,如图: 其中可看出&#xff0…

果汁脱色树脂,制糖行业脱色,医药行业脱色

具有控制孔径的大孔强碱性Ⅰ型阴特种脱色用离子交换树脂 Tulsimer A-722是一款具有便于颜色和有机物去除的控制孔径的&#xff0c;专门开发的大孔强碱性Ⅰ型阴离子交换树脂。 Tulsimer A-722 &#xff08;氯型&#xff09;专门应用于糖浆脱色。 Tulsimer A-722由于其本身…

字节真的是宇宙尽头吗?

身边在字节的朋友很多人抱怨很卷&#xff0c;但卷到何种程度?很多人没有直观感受。某乎上一个问题(在字节跳动工作是怎样的?)点赞排名第一的回答生动的解释了字节的卷。 租房的舍友在字节工作。 舍友主卧&#xff0c;我次卧。 合租两个月了&#xff0c;我没见过舍友长什么样。…