环境:
-
element-ui@2.13.2
-
vue@2.6.6
示例:
1. 表格单选
-
方案1
<template> <div class="radio_page"> <div class="selected_num">已选 {{selectedRow.name}}</div> <el-table :data="list" ref="table" :border="true" v-loading="loading" :row-class-name="rowClassName" @select="selectItem"> <el-table-column type="selection" width="50"> </el-table-column> <el-table-column prop="name" label="姓名"> </el-table-column> <el-table-column prop="age" label="年龄"> </el-table-column> </el-table> <el-pagination v-if="total" :total="total" :current-page.sync="pageNo" :page-size="limit" @current-change="handleCurrentChange"> </el-pagination> </div> </template> <script> export default { data() { return { total: 100, pageNo: 1, limit: 10, selectedId: null, // 选中数据id selectedRow: {}, // 选中数据 list: [], // 表格数据 loading: false, // 加载标记 } }, methods: { init() { this.getList(); }, // 模拟接口获取数据 getList() { if (this.loading) return; this.loading = true; setTimeout(() => { this.list = this.createList(); this.loading = false; this.updateTableSelect(); }, 1000); }, // 生成数据 createList() { const { pageNo, limit } = this; const res = []; const baseNum = limit * (pageNo - 1); for (let i = 0; i < limit; i++) { res.push({ id: baseNum + i, name: '姓名' + (baseNum + i), age: baseNum + i }) } return res; }, // 接口返回数据后更新选中状态 updateTableSelect() { this.$nextTick(() => { const list = this.list; const selectedRow = this.selectedRow; const needUpdate = list.find(item => { if (selectedRow && selectedRow.id == item.id) { return true; } return false; }); if (needUpdate) { this.$refs.table.toggleRowSelection(needUpdate, true) } }) }, // 标记选中行增加特殊类 rowClassName({row}) { const selectedRow = this.selectedRow; if (selectedRow && selectedRow.id == row.id) { return 'green'; } return ''; }, // 单行切换选中状态处理 selectItem(selection, row) { this.$refs.table.clearSelection() this.$nextTick(() => { this.$refs.table.toggleRowSelection(row, true); this.selectedRow = row; }) }, // 分页器页码变化 handleCurrentChange(page) { this.pageNo = page; this.getList(); }, }, created() { this.init(); }, } </script> <style lang="stylus"> .radio_page{ .green{ background-color: #ddf7dd; } .el-table__header .el-checkbox{ display none } } </style>
-
方案2
<template> <div class="radio_page"> <div class="selected_num">已选 {{selectedRow.name}}</div> <el-table :data="list" ref="table" :border="true" v-loading="loading" :row-class-name="rowClassName"> <el-table-column label="" align="center" width="50"> <template scope="scope"> <el-radio :label="scope.row.id" v-model="selectedId" @change.native="selectItem(scope.row)"></el-radio> </template> </el-table-column> <el-table-column prop="name" label="姓名"> </el-table-column> <el-table-column prop="age" label="年龄"> </el-table-column> </el-table> <el-pagination v-if="total" :total="total" :current-page.sync="pageNo" :page-size="limit" @current-change="handleCurrentChange"> </el-pagination> </div> </template> <script> export default { data() { return { total: 100, pageNo: 1, limit: 10, selectedId: null, // 选中数据 selectedRow: {}, // 选中数据 list: [], // 表格数据 loading: false, // 加载标记 } }, methods: { init() { this.getList(); }, // 模拟接口获取数据 getList() { if (this.loading) return; this.loading = true; setTimeout(() => { this.list = this.createList(); this.loading = false; }, 1000); }, // 生成数据 createList() { const { pageNo, limit } = this; const res = []; const baseNum = limit * (pageNo - 1); for (let i = 0; i < limit; i++) { res.push({ id: baseNum + i, name: '姓名' + (baseNum + i), age: baseNum + i }) } return res; }, // 标记选中行增加特殊类 rowClassName({row}) { const selectedRow = this.selectedRow; if (selectedRow && selectedRow.id == row.id) { return 'green'; } return ''; }, // 单行切换选中状态处理 selectItem(row) { this.selectedRow = row; }, // 分页器页码变化 handleCurrentChange(page) { this.pageNo = page; this.getList(); }, }, created() { this.init(); }, } </script> <style lang="stylus"> .radio_page{ .green{ background-color: #ddf7dd; } .el-radio__label{ display: none; } } </style>
2. 表格多选
<template>
<div class="check_page">
<div class="selected_num">已选 {{selection.length}} 人</div>
<el-table
:data="list"
ref="table"
:border="true"
v-loading="loading"
:row-class-name="rowClassName"
@select="selectItem"
@select-all="selectAll"
@selection-change="selectionChange">
<el-table-column
type="selection"
width="50">
</el-table-column>
<el-table-column
prop="name"
label="姓名">
</el-table-column>
<el-table-column
prop="age"
label="年龄">
</el-table-column>
</el-table>
<el-pagination
v-if="total"
:total="total"
:current-page.sync="pageNo"
:page-size="limit"
@current-change="handleCurrentChange">
</el-pagination>
</div>
</template>
<script>
export default {
data() {
return {
total: 100,
pageNo: 1,
limit: 10,
selection: [], // 选中数据
list: [], // 表格数据
loading: false, // 加载标记
selectRow: new Map(), // 标记当前选中行
}
},
methods: {
init() {
this.getList();
},
// 模拟接口获取数据
getList() {
if (this.loading) return;
this.loading = true;
setTimeout(() => {
this.list = this.createList();
this.updateTableSelect();
this.loading = false;
}, 1000);
},
// 生成数据
createList() {
const { pageNo, limit } = this;
const res = [];
const baseNum = limit * (pageNo - 1);
for (let i = 0; i < limit; i++) {
res.push({
id: baseNum + i,
name: '姓名' + (baseNum + i),
age: baseNum + i
})
}
return res;
},
// 接口返回数据后更新选中状态
updateTableSelect() {
const selection = this.selection;
if (!selection.length) return;
this.$nextTick(() => {
const list = this.list;
const selectionMap = new Map();
selection.forEach(item => {
selectionMap.set(item.id, 1);
});
const needUpdate = list.filter(item => {
if (selectionMap.has(item.id)) {
return true;
}
return false;
});
needUpdate.forEach(item => {
this.$refs.table.toggleRowSelection(item, true)
});
})
},
// 标记选中行增加特殊类
rowClassName({row}) {
const selectRow = this.selectRow;
if (selectRow.has(row.id)) {
return 'green';
}
return '';
},
// 单行切换选中状态处理
selectItem(selection, row) {
const selected = selection.find(item => item.id == row.id);
if (selected) {
this.selection = [ ...this.selection, row ];
} else {
this.selection = this.selection.filter(item => item.id != row.id)
}
},
// 全选、全取消处理
selectAll(newSelected) {
if (newSelected.length == 0) {
const cancelMap = new Map();
this.list.forEach(item => {
cancelMap.set(item.id, item);
});
const newSelected = this.selection.filter(item => {
if (cancelMap.has(item.id)) {
return false;
}
return true;
});
this.selection = [...newSelected];
} else {
const selectedMap = new Map();
newSelected.forEach(item => {
selectedMap.set(item.id, item);
});
const oldSelected = this.selection.filter(item => {
if (selectedMap.has(item.id)) {
return false;
}
return true;
})
this.selection = [...oldSelected, ...newSelected];
}
},
// 选中状态变化,只会记录当前页,因此用于生成当前页选中行数据
selectionChange(selection) {
const newMap = new Map();
selection.forEach(item => {
newMap.set(item.id, item)
});
this.selectRow = newMap;
},
// 分页器页码变化
handleCurrentChange(page) {
this.pageNo = page;
this.getList();
},
},
created() {
this.init();
},
}
</script>
<style lang="stylus">
.check_page{
.green{
background-color: #ddf7dd;
}
}
</style>
注意:
更新选中状态都是放到了$nextTick
里面,否则选中行高亮会有问题。