记录一下我使用ElementUi遇到的坑,欢迎朋友们补充。
1. El-table里想要每一行数据都有el-checkbox,做下图的效果时,要注意el-checkbox-group绑定的数据类型。
(PS:更常规的写法是直接用el-table原生自带的checkbox来实现选择、全选功能,但是产品说啥我就做啥,这里就讨论我们使用的这个方案会遇到的坑)
因为官网提供的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>
我一开始写错的代码:
<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。
出现的问题:
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。