论项目中不慎踩过的小坑

347 阅读3分钟

1.Vue中通过v-for指令动态生成多级表头时,如果以都以index作为key,极有可能导致自定义列显示隐藏操作时出现表格错乱的问题

        <el-table-column
          v-for="(col,index) in tableCols"
          :key="index"
          :label="col.label"
          :prop="col.prop">
          <template v-if="col.children">
            <el-table-column
            v-for="(child,cindex) in col.children"
              :key="cindex"
              :label="child.label"
              :prop="child.prop">
            </el-table-column>
          </template>
        </el-table-column>

分析问题:如上代码中,一级和二级表头在动态渲染是分别以index和cindex作为key,我们知道,这里的index和cindex其实都是指循环时的下标0123...,也就是说,这样渲染结束之后,一级表头的与二级表头会产生重复的key,虽然初次渲染时不会有问题,但是一旦涉及到表格列配置或动态显示隐藏导致的表头数据变更,就会触发到vue中的核心--diff算法。众所周知,key是diff算法中判断页面内容是否需要重绘的关键指标,同一个表格中出现重复的key会对diff算法产生干扰,进而导致表格渲染结果错乱。
解决问题:

        <el-table-column
          v-for="(col,index) in tableCols"
          :key="col.prop"
          :label="col.label"
          :prop="col.prop">
          <template v-if="col.children">
            <el-table-column
            v-for="(child,cindex) in col.children"
              :key="child.prop"
              :label="child.label"
              :prop="child.prop">
            </el-table-column>
          </template>
        </el-table-column>

2.在一个绘图项目中,发现给某个元素绑定了@click事件但是无论如何都没办法触发

分析问题:因为项目中绘图的定制性较高,无法使用echarts或者其他开源库,所以使用原生html与canvas绘制,为了实现画布、图例等布局效果使用了绝对定位,相当于对画布和图例进行了叠加,但由于先使用div绘制了图例,后绘制的canvas,即canvas是覆盖于div图例之上的,每次点击图例元素的位置相当于都是点击在了canvas上,导致为图例绑定的@click事件总是无法触发
解决问题:为图例元素设置z-index,保证其图层位于canvas上方

3.el-dialog嵌套导致无渲染

问题描述:项目中利用el-dialog封装了自定义的进度条组件,当时的业务场景是,某个地方的对话框加载时需要复杂且耗时的逻辑处理,所以需要在对话框出现的同时显示进度条,我就在对话框组件内引用了进度条组件,这样就就无形中产生了el-dialog嵌套的问题,导致进度条组件始终无法渲染。
解决问题:在对话框组件和自定义的进度条组件需要同时使用时,使其并列而非嵌套

4.v-loading与html2canvas同时使用时导致loading效果总是不能及时出现

问题描述:众所周知,html2canvas可以实现对页面内容进行截图,但是遇到稍微复杂一点的页面结构时会比较耗时,为了提升用户体验,我们希望在html2canvas执行前显示Loading,执行结束之后Loading消失。但是,在实际使用时,发现html2canvas会阻塞进程,导致loading无法在我们希望的时机出现和消失。
解决问题:先让loading出现,然后将html2canvas的逻辑处理放在setTimeout中执行,然后在html2canvas的成功回调中让loading消失,这样可以保证loading在我们需要时正确显隐。

5.el-form的resetField()方法无法清空表单内容

解决方法:保证表单项el-form-item中有prop属性且prop值与表单数据源的key一致

image.png

6.el-form的表单验证方法validate()总是不进回调

解决方法:如果有自定义校验规则,必须保证确保所有出口(即每种条件)都有callback

image.png

参考文档:www.freesion.com/article/740…

7.el-input-number希望默认值为空而不是0

解决方法:1.设置属性 :min="null" 2.设置model绑定值为undefined 2种方法2选1都可以实现默认值为空

8.使用iframe是通过postMessage传参时第一次偶尔发送不过去

原因分析:postMessage代码执行时,iframe元素坑尚未加载完成,因此iframe.contentWindow.postMessage方法执行失败 解决方法:在iframe元素加载完成后再发送数据

var iframe = document.getElementById('iframe');
iframe.onload = () => {
    iframe.contentWindow.postMessage(params, '*');//'*'可以解决跨域问题
}