mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-11-30 02:08:12 +08:00
* fix(components): [table-column] column miss update due to key (#8528) * fix(components): [table-column] column miss update due to key (#8528) * fix(components): [table-column] ts lint (#8528) * fix(components): [table-column] column miss update due to key (#8528) * fix(components): [table-column] states.updateOrderFns remove ref (#8528) * fix(components): [table-column] add test for table (#8528) * Update packages/components/table/src/store/watcher.ts Co-authored-by: qiang <qw13131wang@gmail.com> * fix(components): [table-column] fix ts define (#8528) * fix(components): [table-column] column miss update due to key (#8528) --------- Co-authored-by: qiang <qw13131wang@gmail.com>
This commit is contained in:
parent
65a9cca1ed
commit
9721912342
@ -1554,4 +1554,53 @@ describe('Table.vue', () => {
|
||||
await doubleWait()
|
||||
expect(wrapper.vm.selected.length).toEqual(3)
|
||||
})
|
||||
it('change columns order when use v-for & key to render table', async () => {
|
||||
const wrapper = mount({
|
||||
components: {
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
},
|
||||
template: `
|
||||
<button class="change-column" @click="changeColumnData"></button>
|
||||
<el-table :data="testData">
|
||||
<el-table-column
|
||||
v-for="item in columnsData"
|
||||
:prop="item.prop"
|
||||
:label="item.label"
|
||||
:key="item.prop" />
|
||||
</el-table>
|
||||
`,
|
||||
data() {
|
||||
const testData = getTestData() as any
|
||||
|
||||
return {
|
||||
testData,
|
||||
columnsData: [
|
||||
{ label: 'name', prop: 'name' },
|
||||
{ label: 'release', prop: 'release' },
|
||||
{ label: 'director', prop: 'director' },
|
||||
{ label: 'runtime', prop: 'runtime' },
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeColumnData() {
|
||||
;[this.columnsData[0], this.columnsData[1]] = [
|
||||
this.columnsData[1],
|
||||
this.columnsData[0],
|
||||
]
|
||||
},
|
||||
},
|
||||
})
|
||||
await doubleWait()
|
||||
wrapper.find('.change-column').trigger('click')
|
||||
await doubleWait()
|
||||
expect(wrapper.find('.el-table__header').findAll('.cell')[0].text()).toBe(
|
||||
'release'
|
||||
)
|
||||
expect(wrapper.find('.el-table__header').findAll('.cell')[1].text()).toBe(
|
||||
'name'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -73,7 +73,8 @@ function useStore<T>() {
|
||||
insertColumn(
|
||||
states: StoreStates,
|
||||
column: TableColumnCtx<T>,
|
||||
parent: TableColumnCtx<T>
|
||||
parent: TableColumnCtx<T>,
|
||||
updateColumnOrder: () => void
|
||||
) {
|
||||
const array = unref(states._columns)
|
||||
let newColumns = []
|
||||
@ -89,6 +90,7 @@ function useStore<T>() {
|
||||
}
|
||||
sortColumn(newColumns)
|
||||
states._columns.value = newColumns
|
||||
states.updateOrderFns.push(updateColumnOrder)
|
||||
if (column.type === 'selection') {
|
||||
states.selectable.value = column.selectable
|
||||
states.reserveSelection.value = column.reserveSelection
|
||||
@ -99,10 +101,22 @@ function useStore<T>() {
|
||||
}
|
||||
},
|
||||
|
||||
updateColumnOrder(states: StoreStates, column: TableColumnCtx<T>) {
|
||||
const newColumnIndex = column.getColumnIndex?.()
|
||||
if (newColumnIndex === column.no) return
|
||||
|
||||
sortColumn(states._columns.value)
|
||||
|
||||
if (instance.$ready) {
|
||||
instance.store.updateColumns()
|
||||
}
|
||||
},
|
||||
|
||||
removeColumn(
|
||||
states: StoreStates,
|
||||
column: TableColumnCtx<T>,
|
||||
parent: TableColumnCtx<T>
|
||||
parent: TableColumnCtx<T>,
|
||||
updateColumnOrder: () => void
|
||||
) {
|
||||
const array = unref(states._columns) || []
|
||||
if (parent) {
|
||||
@ -125,6 +139,9 @@ function useStore<T>() {
|
||||
}
|
||||
}
|
||||
|
||||
const updateFnIndex = states.updateOrderFns.indexOf(updateColumnOrder)
|
||||
updateFnIndex > -1 && states.updateOrderFns.splice(updateFnIndex, 1)
|
||||
|
||||
if (instance.$ready) {
|
||||
instance.store.updateColumns() // hack for dynamics remove column
|
||||
instance.store.scheduleLayout()
|
||||
|
@ -60,6 +60,7 @@ function useWatcher<T>() {
|
||||
const leafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
||||
const fixedLeafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
||||
const rightFixedLeafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
||||
const updateOrderFns: (() => void)[] = []
|
||||
const leafColumnsLength = ref(0)
|
||||
const fixedLeafColumnsLength = ref(0)
|
||||
const rightFixedLeafColumnsLength = ref(0)
|
||||
@ -517,6 +518,7 @@ function useWatcher<T>() {
|
||||
leafColumns,
|
||||
fixedLeafColumns,
|
||||
rightFixedLeafColumns,
|
||||
updateOrderFns,
|
||||
leafColumnsLength,
|
||||
fixedLeafColumnsLength,
|
||||
rightFixedLeafColumnsLength,
|
||||
|
@ -55,6 +55,7 @@ export default defineComponent({
|
||||
getPropsData,
|
||||
getColumnElIndex,
|
||||
realAlign,
|
||||
updateColumnOrder,
|
||||
} = useRender(props as unknown as TableColumnCtx<unknown>, slots, owner)
|
||||
|
||||
const parent = columnOrTableParent.value
|
||||
@ -140,14 +141,16 @@ export default defineComponent({
|
||||
owner.value.store.commit(
|
||||
'insertColumn',
|
||||
columnConfig.value,
|
||||
isSubColumn.value ? parent.columnConfig.value : null
|
||||
isSubColumn.value ? parent.columnConfig.value : null,
|
||||
updateColumnOrder
|
||||
)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
owner.value.store.commit(
|
||||
'removeColumn',
|
||||
columnConfig.value,
|
||||
isSubColumn.value ? parent.columnConfig.value : null
|
||||
isSubColumn.value ? parent.columnConfig.value : null,
|
||||
updateColumnOrder
|
||||
)
|
||||
})
|
||||
instance.columnId = columnId.value
|
||||
|
@ -189,6 +189,10 @@ function useRender<T>(
|
||||
return Array.prototype.indexOf.call(children, child)
|
||||
}
|
||||
|
||||
const updateColumnOrder = () => {
|
||||
owner.value.store.commit('updateColumnOrder', instance.columnConfig.value)
|
||||
}
|
||||
|
||||
return {
|
||||
columnId,
|
||||
realAlign,
|
||||
@ -200,6 +204,7 @@ function useRender<T>(
|
||||
setColumnRenders,
|
||||
getPropsData,
|
||||
getColumnElIndex,
|
||||
updateColumnOrder,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,7 @@ import TableBody from './table-body'
|
||||
import TableFooter from './table-footer'
|
||||
import useUtils from './table/utils-helper'
|
||||
import useStyle from './table/style-helper'
|
||||
import useKeyRender from './table/key-render-helper'
|
||||
import defaultProps from './table/defaults'
|
||||
import { TABLE_INJECTION_KEY } from './tokens'
|
||||
import { hColgroup } from './h-helper'
|
||||
@ -272,6 +273,8 @@ export default defineComponent({
|
||||
return props.emptyText || t('el.table.emptyText')
|
||||
})
|
||||
|
||||
useKeyRender(table)
|
||||
|
||||
return {
|
||||
ns,
|
||||
layout,
|
||||
|
27
packages/components/table/src/table/key-render-helper.ts
Normal file
27
packages/components/table/src/table/key-render-helper.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import type { Table } from './defaults'
|
||||
|
||||
export default function useKeyRender(table: Table<[]>) {
|
||||
const observer = ref<MutationObserver>()
|
||||
|
||||
const initWatchDom = () => {
|
||||
const el = table.vnode.el
|
||||
const columnsWrapper = (el as HTMLElement).querySelector('.hidden-columns')
|
||||
const config = { childList: true, subtree: true }
|
||||
const updateOrderFns = table.store.states.updateOrderFns
|
||||
observer.value = new MutationObserver(() => {
|
||||
updateOrderFns.forEach((fn: () => void) => fn())
|
||||
})
|
||||
|
||||
observer.value.observe(columnsWrapper!, config)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// fix https://github.com/element-plus/element-plus/issues/8528
|
||||
initWatchDom()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
observer.value?.disconnect()
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user