el-table中每行嵌套的el-dialog

文章描述了在ElementUI的el-table组件中嵌套el-dialog时遇到的渲染卡顿问题,分析了由于数据量大和重复渲染导致的性能下降。作者尝试了数据分页和动态加载加载样式的方法,但未解决问题。最终解决方案是将dialog移出table之外,避免重复渲染。文章强调了理解和优化底层渲染逻辑的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

继上次写博客记录的el-table+el-dialog的bug之后--

elementui el-table中每行嵌套的el-dialog的scope取值bug_el-table 行嵌套_FC_oder的博客-优快云博客s

今天又遇到了类似的问题:在el-table-column中嵌套使用el-dialog时,出现了dialog内容加载卡顿的问题

问题代码:(偷懒直接贴了上篇博客的)

          <el-table-column align="right">
            <template slot-scope="scope">
              <el-button
                size="mini"
                @click="handleEdit(scope.$index)"
              >
                <i class="el-icon-info"></i> 详细信息 {{ scope.$index }}
              </el-button>
              <el-dialog
                :title="`详细信息${scope.$index}`"
                :visible.sync="dialogVisible"
                width="25%"
                :append-to-body="true"
                :lock-scroll="false"
              >
                {{ scope.$index }}
                <el-scrollbar>
                  <div class="list-item">
                    <el-table :data="listDataCopy[scope.$index]">
                      <el-table-column
                        label="属性"
                        prop="ParaDesc">
                      </el-table-column>
                      <el-table-column
                        label="数值"
                        prop="ParaValue">
                      </el-table-column>
                    </el-table>
                  </div>
                </el-scrollbar>
                <span slot="footer" class="dialog-footer">
                <el-button type="primary" @click="dialogVisible = false"
                >知道了</el-button>
              </span>
              </el-dialog>
            </template>
          </el-table-column>

问题分析:

项目中dialog需要渲染的是每种原油的70多种属性的数据,el-table负责对多种原油的属性数据进行渲染,在点击详情后弹出dialog展示对应油种的属性数据。

项目一开始的方案是在页面mounted钩子中直接向后端请求页面中所有的数据。然后在测试详情按钮的时候发现了本篇文章所描述的问题。

一开始认为问题出在el-table中所需渲染的列表(从后端请求得到的)数据过大导致的问题,这边让后端做了数据分页后,发现问题没有得到明显改善。

因此这边想到的第二个方法是在点击详情后,给dialog中加个elementui的加载样式,等到dialog中的元素渲染完毕后再关闭加载样式。这边采用了动态增加加载样式的方式,获取到classname为el-scrollbar__wrap的元素列表。

setTimeout(async ()=>{
        const elem = document.getElementsByClassName('el-scrollbar__wrap')
        console.log(elem)
        const loading = this.$loading({
          lock: true,
          target: elem[0],
          spinner: 'el-icon-loading',
          background: 'rgba(255, 255, 255, 0.5)'
        });
        let form = new FormData()

        // 向后端请求对应id的原油数据
        form.append('id', this.id)
        const res = await this.SENDMESSAGE(form)

        loading.close()
        res.data.data.forEach((val,key)=>{
          this.dialogData.push({
            paraDesc: labelsAll[key],
            paraValue: val
          })
        })
      },200)

然而在测试时发现并没有出现期望的加载样式,并且打印出来的elem足足25个之多。

这边终于才恍然大悟,原来dialog重复渲染了多次,在点击某个详情按钮时,增加的加载样式并不一定是显示在最顶层的dialog上。也正因为重复渲染,在dialog中节点数量较多的时候,会造成明显的卡顿。

而一开始未能及时排查出重复渲染问题的原因是,虽然重复渲染了多次dialog,但每个dialog所绑定的开启事件和关闭事件是完全相同的,打开和关闭dialog过程中除了加载略卡,其他并无异样。

因此,最终的解决方案也很简单,将dialog提出到el-table之外即可。

随后,这里我也是抱着一定的好奇心稍微研究了一下el-table的源码。 其中,el-table-column的核心代码可以参考这篇博客:

element-ui的el-table源码分析 - 掘金

可以看到,el-table底层的逻辑是将待渲染的列表遍历一遍,同时column内的template中所有的元素会被遍历渲染。也验证了我的猜想。

总结:

目前认为最优的解决方案是将写在column内的dialog抽出在外层div写。因为el-table底层的逻辑是将待渲染的列表遍历一遍,同时column内的template中所有的元素会被遍历渲染。如果dialog写在column内除了会发生上一篇文章提到的问题之外,还会因为渲染过多重复节点出现性能问题。

欸,感觉这个问题还挺基础的。第一次发文章碰到这个问题的时候急着赶项目进度,没有仔细分析问题背后的原因。今天再次碰到类似的问题了,才静下心来的进行分析。希望自己在学习的过程中能多多积累类似的追根溯源的经验与能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值