mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-02 11:17:46 +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()
|
await doubleWait()
|
||||||
expect(wrapper.vm.selected.length).toEqual(3)
|
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(
|
insertColumn(
|
||||||
states: StoreStates,
|
states: StoreStates,
|
||||||
column: TableColumnCtx<T>,
|
column: TableColumnCtx<T>,
|
||||||
parent: TableColumnCtx<T>
|
parent: TableColumnCtx<T>,
|
||||||
|
updateColumnOrder: () => void
|
||||||
) {
|
) {
|
||||||
const array = unref(states._columns)
|
const array = unref(states._columns)
|
||||||
let newColumns = []
|
let newColumns = []
|
||||||
@ -89,6 +90,7 @@ function useStore<T>() {
|
|||||||
}
|
}
|
||||||
sortColumn(newColumns)
|
sortColumn(newColumns)
|
||||||
states._columns.value = newColumns
|
states._columns.value = newColumns
|
||||||
|
states.updateOrderFns.push(updateColumnOrder)
|
||||||
if (column.type === 'selection') {
|
if (column.type === 'selection') {
|
||||||
states.selectable.value = column.selectable
|
states.selectable.value = column.selectable
|
||||||
states.reserveSelection.value = column.reserveSelection
|
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(
|
removeColumn(
|
||||||
states: StoreStates,
|
states: StoreStates,
|
||||||
column: TableColumnCtx<T>,
|
column: TableColumnCtx<T>,
|
||||||
parent: TableColumnCtx<T>
|
parent: TableColumnCtx<T>,
|
||||||
|
updateColumnOrder: () => void
|
||||||
) {
|
) {
|
||||||
const array = unref(states._columns) || []
|
const array = unref(states._columns) || []
|
||||||
if (parent) {
|
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) {
|
if (instance.$ready) {
|
||||||
instance.store.updateColumns() // hack for dynamics remove column
|
instance.store.updateColumns() // hack for dynamics remove column
|
||||||
instance.store.scheduleLayout()
|
instance.store.scheduleLayout()
|
||||||
|
@ -60,6 +60,7 @@ function useWatcher<T>() {
|
|||||||
const leafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
const leafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
||||||
const fixedLeafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
const fixedLeafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
||||||
const rightFixedLeafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
const rightFixedLeafColumns: Ref<TableColumnCtx<T>[]> = ref([])
|
||||||
|
const updateOrderFns: (() => void)[] = []
|
||||||
const leafColumnsLength = ref(0)
|
const leafColumnsLength = ref(0)
|
||||||
const fixedLeafColumnsLength = ref(0)
|
const fixedLeafColumnsLength = ref(0)
|
||||||
const rightFixedLeafColumnsLength = ref(0)
|
const rightFixedLeafColumnsLength = ref(0)
|
||||||
@ -517,6 +518,7 @@ function useWatcher<T>() {
|
|||||||
leafColumns,
|
leafColumns,
|
||||||
fixedLeafColumns,
|
fixedLeafColumns,
|
||||||
rightFixedLeafColumns,
|
rightFixedLeafColumns,
|
||||||
|
updateOrderFns,
|
||||||
leafColumnsLength,
|
leafColumnsLength,
|
||||||
fixedLeafColumnsLength,
|
fixedLeafColumnsLength,
|
||||||
rightFixedLeafColumnsLength,
|
rightFixedLeafColumnsLength,
|
||||||
|
@ -55,6 +55,7 @@ export default defineComponent({
|
|||||||
getPropsData,
|
getPropsData,
|
||||||
getColumnElIndex,
|
getColumnElIndex,
|
||||||
realAlign,
|
realAlign,
|
||||||
|
updateColumnOrder,
|
||||||
} = useRender(props as unknown as TableColumnCtx<unknown>, slots, owner)
|
} = useRender(props as unknown as TableColumnCtx<unknown>, slots, owner)
|
||||||
|
|
||||||
const parent = columnOrTableParent.value
|
const parent = columnOrTableParent.value
|
||||||
@ -140,14 +141,16 @@ export default defineComponent({
|
|||||||
owner.value.store.commit(
|
owner.value.store.commit(
|
||||||
'insertColumn',
|
'insertColumn',
|
||||||
columnConfig.value,
|
columnConfig.value,
|
||||||
isSubColumn.value ? parent.columnConfig.value : null
|
isSubColumn.value ? parent.columnConfig.value : null,
|
||||||
|
updateColumnOrder
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
owner.value.store.commit(
|
owner.value.store.commit(
|
||||||
'removeColumn',
|
'removeColumn',
|
||||||
columnConfig.value,
|
columnConfig.value,
|
||||||
isSubColumn.value ? parent.columnConfig.value : null
|
isSubColumn.value ? parent.columnConfig.value : null,
|
||||||
|
updateColumnOrder
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
instance.columnId = columnId.value
|
instance.columnId = columnId.value
|
||||||
|
@ -189,6 +189,10 @@ function useRender<T>(
|
|||||||
return Array.prototype.indexOf.call(children, child)
|
return Array.prototype.indexOf.call(children, child)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateColumnOrder = () => {
|
||||||
|
owner.value.store.commit('updateColumnOrder', instance.columnConfig.value)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
columnId,
|
columnId,
|
||||||
realAlign,
|
realAlign,
|
||||||
@ -200,6 +204,7 @@ function useRender<T>(
|
|||||||
setColumnRenders,
|
setColumnRenders,
|
||||||
getPropsData,
|
getPropsData,
|
||||||
getColumnElIndex,
|
getColumnElIndex,
|
||||||
|
updateColumnOrder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ import TableBody from './table-body'
|
|||||||
import TableFooter from './table-footer'
|
import TableFooter from './table-footer'
|
||||||
import useUtils from './table/utils-helper'
|
import useUtils from './table/utils-helper'
|
||||||
import useStyle from './table/style-helper'
|
import useStyle from './table/style-helper'
|
||||||
|
import useKeyRender from './table/key-render-helper'
|
||||||
import defaultProps from './table/defaults'
|
import defaultProps from './table/defaults'
|
||||||
import { TABLE_INJECTION_KEY } from './tokens'
|
import { TABLE_INJECTION_KEY } from './tokens'
|
||||||
import { hColgroup } from './h-helper'
|
import { hColgroup } from './h-helper'
|
||||||
@ -272,6 +273,8 @@ export default defineComponent({
|
|||||||
return props.emptyText || t('el.table.emptyText')
|
return props.emptyText || t('el.table.emptyText')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useKeyRender(table)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ns,
|
ns,
|
||||||
layout,
|
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