有意思的bug | el-dialog 嵌套时的生命周期问题

问题描述

涉及三个页面:

首页(page)->弹窗(edit)->子弹窗(inside form)

情况:

首页点编辑时带入form,进入弹窗,弹窗带入form进子弹窗

第一次点击编辑时,弹窗子弹窗有值

第二次编辑时,弹窗子弹窗没有值

涉及代码:

add.vue

javascript 复制代码
<template>
    ///
    <inside-form
        ref="handleInside"
        :enum-data="enumData"
        :type="form.supplierType"
    :inside-form="form">
    </inside-form>
    ///
</template>

<script>
    close() {
      this.form = Object.assign({}, {
        supplierType: 1,
        notes: '',
        attachmentTOList: []
      })
      ///
      this.dialogVisible = false
    },
</script>

insideForm.vue

xml 复制代码
<script>
    props:{
        // 编辑模式时带入表单
        insideForm: {
          type: Object,
          default: () => {
            return {}
          }
        },
    },
    watch:{
        // 编辑模式时分配表单
        insideForm: {
          deep: true,
          immediate: true,
          handler(newObj) {
            // 编辑模式 第一次 进行赋值
            if(newObj && Object.keys(newObj).length && !this.firstType) {
              Object.assign(this.form[this.type], newObj)
            }
          }
        },
    }
    data() {
        return {
            ///
            form: {
                ///
            }
            firstType: null,
        }
    }
    mounted() {
      this.firstType = this.type
    },
</script>

解决办法

在子弹窗加入生命周期观察代码

在页面通过vue插件查看数据走向

发现:

在第一次关闭外层弹窗的时候,首先依次执行了子弹窗的beforeDestory 和 destroyed,最后执行了一次子弹窗的mounted!

私以为:

是关闭外层弹窗调用了close方法,里面改变了this.form的值,导致子组件被重新渲染

其实是:

外层弹窗带了destroy-on-close会导致关闭弹窗时触发了子组件的mounted

因此:

去掉destroy-on-close

发现:

在第一次打开外层弹窗的时候,执行子弹窗的mounted;在关闭外层弹窗的时候,不执行子弹窗的任何生命周期

再次打开外层弹窗的时候,不执行子弹窗的mounted,虽然页面上有值,但是是子弹窗的残留值,并未清空

希望:

能够自己把控子组件的生命周期,从创建到销毁。即希望在正确的地方调用子组件的清空方法

最后的解决方式:

add.vue

ini 复制代码
<template>
    ///
    <inside-form
        v-if="dialogVisible"
        ref="handleInside"
        :enum-data="enumData"
        :type="form.supplierType"
    :inside-form="form">
    </inside-form>
    ///
</template>

insideForm.vue

kotlin 复制代码
destroyed() {
  this.clearCertainForm()
},
methods: {
    // 清空子组件内容
    clearCertainForm() {
      this.form = [///]
      this.merchandiserName = ''
      this.firstType = null
      this.channelDisabled = true
    }
}

在外层弹窗组件引用处,加入v-if,当外层弹窗关闭时,触发v-if将子组件从DOM树上移除,从而触发执行子组件的destory生命周期

在子组件中,在destroyed中进行子组件的清空操作

总结

  • 数据传输出现问题时,加入生命周期观察代码

  • 抽取子组件时,尽量把握子组件的整个生命周期,从创建到销毁

相关推荐
Highcharts.js1 小时前
缺失数据可视化图表开发实战|Highcharts创建人员出生统计面积图表示例
开发语言·前端·javascript·信息可视化·highcharts·图表开发
LaughingZhu8 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫8 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux9 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水10 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger10 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)10 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态10 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态10 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart10 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter