el-dialog重复打开多个,el-dailog+el-table使用卡顿,处理问题的思维方式

793 阅读3分钟

环境: Vue2,element-UI
需求: 通过el-table的行内按钮控制el-dialog的显隐及弹窗内的内容展示
demo视图如下:

image.png

Vue代码如下:

<script setup>
  import { ref } from "vue"

  defineProps({
    msg: String,
  })

  const tableData = ref([
    {
      date: "2016-05-02",
      name: "王小狗",
      address: "北京市普陀区金沙江路 1518 弄",
    },
    {
      date: "2016-05-04",
      name: "王小猪",
      address: "上海市普陀区金沙江路 1517 弄",
    },
    {
      date: "2016-05-01",
      name: "王小虎",
      address: "杭州市普陀区金沙江路 1519 弄",
    },
  ])

  let dialogVisible = ref(false)

  const openDialog = () => {
    console.log("openDialog")
    dialogVisible.value = true
  }
</script>

<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column prop="date" label="Date" width="180" />
    <el-table-column prop="name" label="Name" width="180" />
    <el-table-column prop="address" label="Address" />
    <el-table-column fixed="right" label="Operations" min-width="120">
      <template #default>
        <el-dialog v-model="dialogVisible" title="Tips" width="500" append-to-body>
          <span>This is a message</span>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="dialogVisible = false">Cancel</el-button>
              <el-button type="primary" @click="dialogVisible = false"> Confirm </el-button>
            </div>
          </template>
        </el-dialog>
        <el-button link type="primary" size="small" @click="openDialog"> openDialog </el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

异常问题:

image.png

在这样的代码结构下,生成了三个弹窗,这个结果让人摸不着头脑,我们还曾尝试在 openDialog 方法中进行打印,想要确认该方法执行了几次

image.png

很明显只执行了一次,这种思维方向其实是错误的。

出现这种明显很奇怪的异常时,正确的思维应当是认清现实,仔细分析异常特征,联系代码结构进行处理,而不是脑子里只有,奇怪啊,怪了卧槽,怎么回事啊,不可能啊,绝对不可能!赛博鬼打墙?踏马的离了大谱了,这什么玩意啊,我怎么总是遇见这种奇怪的事情啊, 要尽量避免这种思维,当出现这种想法的时候,你当前已经不适合再钻牛角尖下去了,应当适当的放下,冷静一下。

异常原因: 这个问题的原因很简单,table中的每一行都是循环出来的,所以,el-table-column 中的所有结构都会重复的被添加到每一行中,我们错误的将 el-dialog 的结构放入了表头,导致会渲染出多个相同的弹窗结构,这进一步导致,你看起来打开的是一个弹窗,其实弹窗后面还有好几个,像千手观音似的...

异常处理: 应将所有的弹窗都放在 template 标签最底部或最顶部,在Vue2中应当放在 template 标签下的根标签最底部或最顶部。

之所以特意记录下这个傻傻的异常,是因为我排查这个问题竟然用了快两个小时,我在处理这个问题的时候,明明知道这个原因,但竟然耗了这么长时间才想到要把 el-dialog 给移出来,我觉得我的思维方式不太对劲,我得想办法控制一下,或调整一下自己处理问题的方式,不能进到坑里就着急,找不到方向,骑驴找驴,戴着帽子找帽子,这是不对的。

最后补充一点,el-dialog 存在一个属性 append-to-body 这个属性默认值是 false 但我们开发时最好将他赋为 true 不然会影响结构布局,弹窗虽然时定位的,脱离了文档流,开启了新的层叠上下文,但如果你有多个全屏 fixed 定位时,会出现很奇怪的展示。其次放在外部,也方便调试查看。