Element-Ui避坑指南

476 阅读4分钟

记录一下我使用ElementUi遇到的坑,欢迎朋友们补充。

1. El-table里想要每一行数据都有el-checkbox,做下图的效果时,要注意el-checkbox-group绑定的数据类型。

(PS:更常规的写法是直接用el-table原生自带的checkbox来实现选择、全选功能,但是产品说啥我就做啥,这里就讨论我们使用的这个方案会遇到的坑)

image.png

因为官网提供的checkbox的用法模板代码如下: 所以我第一次写这个功能的时候,el-checkbox-group绑定的数据类型跟官网一致:v-model="checkedCities"。

<template>
  <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
  <div style="margin: 15px 0;"></div>
  <el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
    <el-checkbox v-for="city in cities" :label="city" :key="city">{{city}}</el-checkbox>
  </el-checkbox-group>
</template>

image.png

我一开始写错的代码:
<el-checkbox-group v-model="selectedList" @change="changeClearItemList">
    <el-checkbox v-for="(item,index) in row.labelList" :key="index" :label="item" style="display: inherit;">{{ item }}<br></el-checkbox>
</el-checkbox-group>

我按照elementui的模板来写的,我觉得一个table里面的所有checkbox选项都用一个数组记录就可以了。

会出现的问题:checkbox里面的选项,每一行的数据都不是固定数量的,而且不同行里面的数据可能会有重复的。那么在没有给每一个checkbox数据设定id值做区分的情况下,key值一般是用index,那么存储进数组checkedCities里后,el-checkbox-group是无法分辨出到底对哪一行的数据打勾了。

那么你对第一行F0101 xxx的“测试一”打勾的话,第二行F0102的“测试一”也会被勾选上,因为在el-checkbox-group看来,这就是同一个数据。

如果你可以保证数据在每一行都是固定的,或者数据有id值作为唯一标识与key值绑定,其实更推荐用单个数组去存储。因为这样子el-checkbox-group可以非常直接管理一整个table里面的所有选项数据。

我修改的代码:
<el-checkbox-group v-model="row.selectedList" @change="changeClearItemList">
    <el-checkbox v-for="(item,index) in row.labelList" :key="index" :label="item" style="display: inherit;">{{ item }}<br></el-checkbox>
</el-checkbox-group>

改动的点是:el-checkbox-group绑定的数据是v-model="row.selectedList",也就是说,每一行的数据都有自己的一个数组来存储,那么就会有很多个数组去记录每一行的信息。

一般row.xxx都是后端返回的数据,所以我们在拿到数据后,要自己遍历生成row.selectedList的数组用于存储。并且因为el-checkbox-group绑定的数据是多个数组,所以全选的情况就要我们自己写个函数来判断了,比一开始的方案要麻烦,但是为了不出现bug都是值得的。

目前我认为优化方案只有两种: ①前端可以像我说的这样,修改绑定的数据结构来避免这个bug。 ②后端在返回每一个行的数据时,搭配一个id值去绑定key,这样就可以保证数据的唯一性了。

2.el-table表头用了checkbox,但是渲染效果不佳。

目前的需求是:点击按钮1 ,出现弹出框,是下图一的展示效果。 点击按钮2,出现弹出框,是下图二的展示效果。

弹出框的title是不一样的,我们用title作为if判断条件,去决定table的表头展示的是正常数据还是checkbox。

image.png

image.png

出现的问题:

table表头的渲染效果总是出问题,title的展示正常、v-if的判断条件没写错、其他的数据展示也很正常,但是el-table表头的渲染就是不尽如人意。不是单纯地反着来,而是你每次打开这个页面的渲染情况都不确定(因为和你上一次打开的页面有关)

我的第一个解决方案:

这个是是非常常规的、也比较笨的暴力方法:既然是因为数据渲染出问题了,那么我们就给el-table加个v-if值,v-if='update',update设置为布尔值,在每一个打开页面的时候,把update值更新一下,取反,然后用nextTick重新渲染一下el-table。

这样子确实解决了问题,但是实际上只有表头的checkbox的那个位置是渲染出错的,所以把el-table一整个重新渲染其实是造成了资源的浪费,其他地方的数据都很正常啊。

我的第二个解决方案:
      <el-table :data="dataViewerDialog.tableData" border class="el_table">
        <el-table-column label="sheet名称" property="sheetName" />
        <el-table-column :key="tableKey">

在el-table-column加个key值,一般来说key值都是用index,或者xx.id这种具有唯一性的值,但是我这里用的tableKey是布尔值。在我每一次进入页面、修改table里的checkbox选项、修改表头checkbox的选项时(就是跟它有关的函数)我都去修改这个值:this.tableKey = !this.tableKey。

因为el-table-column是这一列数据,有了key值就vue就可以更精准去渲染。

Key值的重要性其实都是在细节里体现的,很多时候vue的渲染都可以在没有key的情况下成功执行,所以key值常常是绑定index值的(vue官方是不推荐这样做,但是很方便,所以功能简单的情况下确实就这样用了)。一般遇到渲染效果不佳的时候,可以考虑一下是不是可以通过key值去处理bug。