前言
第一次发布CSDN文章,写的不好请见谅。
首先来看一下实现的效果。
在gif中,我添加了row-click事件,所以点击tr也可以选中。下面给大家看一下代码。
代码是在element官方文档上复制下来后修改的。下面是链接:
组件 | Elementhttps://element.eleme.cn/#/zh-CN/component/table%23duo-xuan
代码部分
HTML
<div id="app">
<template>
<el-table
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
@row-click="myrowClick" //主要是这个myrowClick方法
@select="mySelect" // 以及这个mySelect方法
highlight-selection-row
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="日期"
width="120">
<template slot-scope="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="120">
</el-table-column>
<el-table-column
prop="address"
label="地址"
show-overflow-tooltip>
</el-table-column>
</el-table>
<div style="margin-top: 20px">
<el-button @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button>
<el-button @click="toggleSelection()">取消选择</el-button>
</div>
</template>
</div>
JS代码
var Main = {
data() {
return {
tableData: [
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-08",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-06",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-07",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
}
],
multipleSelection: []
};
},
methods: {
toggleSelection(rows) {
if (rows) {
rows.forEach((row) => {
this.$refs.multipleTable.toggleRowSelection(row);
});
} else {
this.$refs.multipleTable.clearSelection();
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
// 这个方法用于当点击tr时,触发 选中与取消选中,以及检查 选中数量是否达到阈值
myrowClick(row) {
// 点击
this.$refs.multipleTable.toggleRowSelection(row);
// 判断是否4
this.checkThreeItem();
},
// 这个方法是当点击前面的复选框时,检查 选中数量是否达到阈值
mySelect() {
this.checkThreeItem();
},
checkThreeItem() {
var selection = this.$refs.multipleTable.selection;
// 判断是否4
if (selection.length == 4) {
selection.pop(); // 这里选择了pop元素的形式取消勾选,你也可以使用toggleRowSelection(row,false)
this.redDom(); // 这个方法控制选中的tr闪烁红色背景
}
},
// 这个方法控制选中的tr闪烁红色背景
redDom() {
var rowList = Array.from(
this.$refs.multipleTable.$el.getElementsByClassName("el-table__row")
); // 首先将所有的tr列举出来,这里参考了 AzeShinja 的文章https://blog.csdn.net/AzeShinja/article/details/120762028
var redList = new Array(); // 这里将一会需要被添加红色背景css的标签记录下来
var s = rowList.filter((i) => {
return i.className.includes("selection-row"); // 筛选出所有的现在已经被选中的tr
});
s.forEach((i) => {
i.childNodes.forEach((td) => {
// 这里遍历tr中的所有td, 把这些td添加到redList数组
redList.push(td);
// 这里为td添加存有闪烁css的类名
td.classList.add("red-background");
});
});
console.log(redList);
// 这里需要在动画结束后第一时间把所有的闪烁css类名删除,否则下次触发事件将显示不达预期
// 具体如何不达预期 我就不演示了。如果不删除,则下次不会有动画效果。
setTimeout(() => {
redList.forEach((i) => {
i.classList.remove("red-background");
});
}, 3000);
}
}
};
var Ctor = Vue.extend(Main);
new Ctor().$mount("#app");
CSS
.is-scrolling-none .el-table__body tr.selection-row>.red-background {
animation: myfirst 1s 3;
}
@keyframes myfirst {
0% {background: #ecf5ff;}
50%{background: #ffffff;}
100% {background: rgb(255, 191, 191);}
}
遇到的主要问题及解决
1. 获取table中的tr集合
var rowList = Array.from(
this.$refs.multipleTable.$el.getElementsByClassName("el-table__row")
);
这个方法源自于csdn作者AzeShinjaVue获取el-table中某一行dom元素_el-table 点击某一行怎么获取他是第几个元素-CSDN博客https://blog.csdn.net/AzeShinja/article/details/120762028
2. 当给td添加red-background类名之后,无效果
查看chrome之后,发现我定义的css在element定义的样式的下面,这导致css被element定义的样式覆盖掉了。
解决方法:
给red-background添加更多的父级前缀,最起码要比element定义的样式要多。
所以我这里的red-background在style中要写为
.is-scrolling-none .el-table__body tr.selection-row .red-background {
animation: myfirst 1s 3;
}
我这里是复制了上面截图中element定义的选择器,并结合了el-table的html结构,加上了 .is-scrolling-none
3. 如何使row-select和select事件,同时保证限制选择项的数量
这里有一个逻辑问题。
select事件触发时,element就已经调用了toggleRowSelection方法。也就是说select事件中的selection是最新的selection。
但是row-click事件中,在没有调用toggleRowSelection方法时,selection是旧的selection。
所以,我在这里做了同步,不论当前选择的数量是否小于3,都在row-select中先执行toggleRowSelection。在判断加上这个tr之后是否是4,如果是4,那么就把这个tr踢出去。
我在踢这个动作里使用的是 selection.pop(),可能不是最优解,仅供参考。