项目背景

项目用的是vue3+vite+element plus的Pc项目

问题描述

本地环境一切正常,构建后。偶发下面的报错。然后页面就不可以用了。
当前页面刷新一下后,操作,就不会报错。
后续发现,是点击另外一个页面,再点击该页面就会必现此报错。
在这里插入图片描述

原因分析&&解决

1.查看了别人的解决方案,应该是调用了未渲染的dom;可以使用 v-show 代替 v-if,试了对这边管用。
2. el-table , 如下代码a.b.c 方式 改为 a?.b?.c 写法。我是这种情况

代码片段A:

<el-table-column label="refNum">
              <template #default="scope: any">
                <span>{{ scope.row?.refNum }}</span>
              </template>
            </el-table-column>

更新----- 2024-06-29

上述的代码片段A,是放在 el-dialog 中的。每次报错也是调起el-dialog 弹窗。原因在于el-dialog关闭后,数据引用存放在内存,没有真正被释放。

为什么关闭 el-dialog 后引用不会被清除?

关闭 el-dialog 后引用不会被清除的原因是为了优化性能和用户体验。以下是一些主要原因:

  1. 性能优化:每次打开和关闭对话框时,Vue 并不会销毁和重新创建对话框的 DOM 结构和组件实例,而是简单地控制其可见性。这减少了不必要的组件创建和销毁,从而提高了性能。

  2. 状态保持:在许多应用场景中,用户希望对话框关闭后再次打开时能够保留之前的状态。例如,填写表单时,用户关闭对话框后重新打开,仍然希望看到之前填写的数据。

  3. 实现简单:通过控制可见性而不是销毁组件,可以简化代码的实现和管理。开发者可以通过简单的布尔值控制对话框的显示和隐藏,而不必担心复杂的组件生命周期管理。

代码示例

父组件
<template>
  <el-button @click="dialogVisible = true">Open Dialog</el-button>
  <el-dialog :visible.sync="dialogVisible" title="Dialog Title">
    <p>Some contents...</p>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false
    };
  }
};
</script>
el-dialog 组件的简化实现(概念性)
export default {
  props: {
    visible: {
      type: Boolean,
      required: true
    }
  },
  watch: {
    visible(newVal) {
      this.isVisible = newVal;
    },
    isVisible(newVal) {
      this.$emit('update:visible', newVal);
    }
  },
  data() {
    return {
      isVisible: this.visible
    };
  },
  template: `
    <div v-if="isVisible">
      <slot></slot>
      <button @click="isVisible = false">Close</button>
    </div>
  `
};

在上述简化实现中,el-dialog 组件接收 visible 属性,并通过 watch 监听 visible 属性的变化,来控制内部的 isVisible 状态。同时,当内部的 isVisible 状态改变时,会通过 update:visible 事件通知父组件,从而实现父子组件之间的双向绑定。

这种设计方式使得组件的状态管理更加简洁和高效,避免了不必要的组件销毁和创建,提升了用户体验和应用性能。但也就是会触发数据的更新。当我再次弹出el-dialog 不是同一个,也会复用内存,所以 a.b.c 没有写成a.b?.c的时候在构建 el-table-column 的时候报错。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐