fix(components): [table] the disabled checkbox are selected (#18034)

* fix(components): [table] non selectable items are selected

closed #18021

* docs: update
This commit is contained in:
qiang 2024-09-13 14:13:33 +08:00 committed by GitHub
parent 6b1b086e4a
commit e3bb681984
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 68 additions and 28 deletions

View File

@ -129,6 +129,8 @@ table/single-select
You can also select multiple rows.
After ^(2.8.3), `toggleRowSelection` supports the third parameter `ignoreSelectable` to determine whether to ignore the selectable attribute.
:::demo Activating multiple selection is easy: simply add an `el-table-column` with its `type` set to `selection`.
table/multi-select
@ -320,22 +322,22 @@ table/table-layout
### Table Exposes
| Method | Description | Type |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| clearSelection | used in multiple selection Table, clear user selection | ^[Function]`() => void` |
| getSelectionRows | returns the currently selected rows | ^[Function]`() => any[]` |
| toggleRowSelection | used in multiple selection Table, toggle if a certain row is selected. With the second parameter, you can directly set if this row is selected | ^[Function]`(row: any, selected?: boolean) => void` |
| toggleAllSelection | used in multiple selection Table, toggle select all and deselect all | ^[Function]`() => void` |
| toggleRowExpansion | used in expandable Table or tree Table, toggle if a certain row is expanded. With the second parameter, you can directly set if this row is expanded or collapsed | ^[Function]`(row: any, expanded?: boolean) => void` |
| setCurrentRow | used in single selection Table, set a certain row selected. If called without any parameter, it will clear selection | ^[Function]`(row: any) => void` |
| clearSort | clear sorting, restore data to the original order | ^[Function]`() => void` |
| clearFilter | clear filters of the columns whose `columnKey` are passed in. If no params, clear all filters | ^[Function]`(columnKeys?: string[]) => void` |
| doLayout | refresh the layout of Table. When the visibility of Table changes, you may need to call this method to get a correct layout | ^[Function]`() => void` |
| sort | sort Table manually. Property `prop` is used to set sort column, property `order` is used to set sort order | ^[Function]`(prop: string, order: string) => void` |
| scrollTo | scrolls to a particular set of coordinates | ^[Function]`(options: number \| ScrollToOptions, yCoord?: number) => void` |
| setScrollTop | set vertical scroll position | ^[Function]`(top?: number) => void` |
| setScrollLeft | set horizontal scroll position | ^[Function]`(left?: number) => void` |
| columns ^(2.7.6) | Get table columns context. | ^[array]`TableColumnCtx<T>[]` |
| Method | Description | Type |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| clearSelection | used in multiple selection Table, clear user selection | ^[Function]`() => void` |
| getSelectionRows | returns the currently selected rows | ^[Function]`() => any[]` |
| toggleRowSelection | used in multiple selection Table, toggle if a certain row is selected. With the second parameter, you can directly set if this row is selected | ^[Function]`(row: any, selected?: boolean, ignoreSelectable = true) => void` |
| toggleAllSelection | used in multiple selection Table, toggle select all and deselect all | ^[Function]`() => void` |
| toggleRowExpansion | used in expandable Table or tree Table, toggle if a certain row is expanded. With the second parameter, you can directly set if this row is expanded or collapsed | ^[Function]`(row: any, expanded?: boolean) => void` |
| setCurrentRow | used in single selection Table, set a certain row selected. If called without any parameter, it will clear selection | ^[Function]`(row: any) => void` |
| clearSort | clear sorting, restore data to the original order | ^[Function]`() => void` |
| clearFilter | clear filters of the columns whose `columnKey` are passed in. If no params, clear all filters | ^[Function]`(columnKeys?: string[]) => void` |
| doLayout | refresh the layout of Table. When the visibility of Table changes, you may need to call this method to get a correct layout | ^[Function]`() => void` |
| sort | sort Table manually. Property `prop` is used to set sort column, property `order` is used to set sort order | ^[Function]`(prop: string, order: string) => void` |
| scrollTo | scrolls to a particular set of coordinates | ^[Function]`(options: number \| ScrollToOptions, yCoord?: number) => void` |
| setScrollTop | set vertical scroll position | ^[Function]`(top?: number) => void` |
| setScrollLeft | set horizontal scroll position | ^[Function]`(left?: number) => void` |
| columns ^(2.7.6) | Get table columns context. | ^[array]`TableColumnCtx<T>[]` |
## Table-column API

View File

@ -5,7 +5,7 @@
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column type="selection" :selectable="selectable" width="55" />
<el-table-column label="Date" width="120">
<template #default="scope">{{ scope.row.date }}</template>
</el-table-column>
@ -16,29 +16,36 @@
<el-button @click="toggleSelection([tableData[1], tableData[2]])">
Toggle selection status of second and third rows
</el-button>
<el-button @click="toggleSelection([tableData[1], tableData[2]], false)">
Toggle selection status based on selectable
</el-button>
<el-button @click="toggleSelection()">Clear selection</el-button>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElTable } from 'element-plus'
import type { TableInstance } from 'element-plus'
interface User {
id: number
date: string
name: string
address: string
}
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const multipleTableRef = ref<TableInstance>()
const multipleSelection = ref<User[]>([])
const toggleSelection = (rows?: User[]) => {
const selectable = (row: User) => ![1, 2].includes(row.id)
const toggleSelection = (rows?: User[], ignoreSelectable?: boolean) => {
if (rows) {
rows.forEach((row) => {
// TODO: improvement typing when refactor table
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
multipleTableRef.value!.toggleRowSelection(row, undefined)
multipleTableRef.value!.toggleRowSelection(
row,
undefined,
ignoreSelectable
)
})
} else {
multipleTableRef.value!.clearSelection()
@ -50,36 +57,43 @@ const handleSelectionChange = (val: User[]) => {
const tableData: User[] = [
{
id: 1,
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
id: 2,
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
id: 3,
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
id: 4,
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
id: 5,
date: '2016-05-08',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
id: 6,
date: '2016-05-06',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
id: 7,
date: '2016-05-07',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',

View File

@ -839,6 +839,19 @@ describe('Table.vue', () => {
expect(vm.fireCount).toEqual(2)
expect(vm.selection.length).toEqual(0)
vm.$refs.table.toggleRowSelection(vm.testData[0], undefined, false)
expect(vm.selection.length).toEqual(0)
expect(vm.fireCount).toEqual(2)
// test use second parameter
vm.$refs.table.toggleRowSelection(vm.testData[1], undefined, false)
expect(vm.selection.length).toEqual(1)
expect(vm.fireCount).toEqual(3)
vm.$refs.table.toggleRowSelection(vm.testData[1], false, false)
expect(vm.selection.length).toEqual(0)
expect(vm.fireCount).toEqual(4)
wrapper.unmount()
})

View File

@ -192,13 +192,20 @@ function useWatcher<T>() {
const toggleRowSelection = (
row: T,
selected?: boolean,
emitChange = true
emitChange = true,
ignoreSelectable = false
) => {
const treeProps = {
children: instance?.store?.states?.childrenColumnName.value,
checkStrictly: instance?.store?.states?.checkStrictly.value,
}
const changed = toggleRowStatus(selection.value, row, selected, treeProps)
const changed = toggleRowStatus(
selection.value,
row,
selected,
treeProps,
ignoreSelectable ? undefined : selectable.value
)
if (changed) {
const newSelection = (selection.value || []).slice()
// 调用 API 修改选中值,不触发 select 事件

View File

@ -8,8 +8,12 @@ function useUtils<T>(store: Store<T>) {
const getSelectionRows = () => {
return store.getSelectionRows()
}
const toggleRowSelection = (row: T, selected?: boolean) => {
store.toggleRowSelection(row, selected, false)
const toggleRowSelection = (
row: T,
selected?: boolean,
ignoreSelectable = true
) => {
store.toggleRowSelection(row, selected, false, ignoreSelectable)
store.updateAllSelected()
}
const clearSelection = () => {