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

news/2024/11/23 20:21:15/

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

编辑

 

添加

 

 

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

原因:现在的代码中,获取部门详情这个动作在子组件的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",关闭和打开弹层,销毁和创建组件 --><deptDialogv-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 = truethis.fatherId = idthis.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"<deptDialogv-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.ppmy.cn/news/75929.html

相关文章

python中的range函数|python中的range函数|range()函数详解|Python中range(len())的用法

本期目录 一、range&#xff08;&#xff09;传递不同的参数1、传递一个参数时2、传递两个参数时3、传递三个参数时 二、使用 range() 构建 for 循环三、遍历列表时使用 range(len()) 的用法3.1 直接使用for循环遍历列表 四、利用 range() 生成固定长度的等差数列五、利用 rang…

Flutter 笔记 | Flutter 中的路由、包、资源、异常和调试

路由管理 Flutter中的路由通俗的讲就是页面跳转。在Flutter中通过Navigator组件管理路由导航。并提供了管理堆栈的方法。如&#xff1a;Navigator.push和Navigator.pop Flutter中给我们提供了两种配置路由跳转的方式&#xff1a;1、基本路由&#xff0c; 2、命名路由 普通路…

【Linux Network】I/O多路转接之select

目录 1. 初识select 1.1 select函数原型 1.2 理解select执行过程 1.3 socket就绪条件 1.4 select的特点 1.5 select优缺点 2. 基于select的多人聊天程序 server源代码&#xff1a; client的登录&#xff1a; 结果演示&#xff1a; Linux Network&#x1f337; 1. 初识select 系…

【Linux之IO系统编程学习】文件读写指针位置调整函数(fseek、rewind、ftell)

【Linux之IO系统编程学习】 项目代码获取&#xff1a;https://gitee.com/chenshao777/linux_-io.git &#xff08;麻烦点个免费的Star哦&#xff0c;您的Star就是我的写作动力&#xff01;&#xff09; 06.读写指针调整函数 int fseek(FILE *stream, long offset, int whence…

如何在Centos7中安装Kubernetes

一、概述 Kubernetes&#xff08;[kubə’netis]&#xff09;&#xff0c;简称K8s&#xff0c;是用8代替名字中间的8个字符“ubernete”而成的缩写&#xff0c;它是一个由Google 开源的全新的分布式容器集群管理系统。 二、准备 IP角色内存192.168.1.130master4G192.168.1.1…

股票配资交易系统【实盘】

股票配资系统建设&#xff0c;本文档主要针对实盘股票配资系统。 股票配资交易系统主要包含三部分&#xff1a;App客户端、交易程序服务端、管理后台 App客户端 app客户端是原生应用&#xff0c;非H5生成。客户端主要功能是承接用户的股票订单委托、查询、用户资金转入&#x…

FP独立站支付问题你还没解决?out了!

目前FP独立站是很多跨境卖家的变现方式&#xff0c;但是这类外贸电商会遇到一些收款问题&#xff0c;这些问题很容易就让卖家的资金被冻结、账号被风控、关联账号被限制&#xff0c;损失真是不小。那FP卖家的收款问题该怎么解决呢&#xff1f;往下看。 一、FP独立站常见收款方式…

Linux·深入理解IO复用技术之epoll

目录 1.写在前面 2.初识复用技术和IO复用 3. Linux的IO复用工具概览 4. 初识epoll 5. epoll的底层细节 6.LT模式和ET模式 7.epoll的惊群问题 1.写在前面 今天一起来学习一下高并发实现的的重要基础&#xff1a;I/O复用技术 & epoll原理。 通过本文你将了解到以下内容…