fix(grid): [grid] fix the problem that the view is not updated after dragging the table (#1193)

This commit is contained in:
ajaxzheng 2023-12-28 20:33:00 +08:00 committed by GitHub
parent 17b67bb648
commit 32985afd16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 30 deletions

View File

@ -27,6 +27,7 @@ export default {
// 处理行拖拽
rowDrop() {
this.$nextTick(() => {
// refresh是否在拖拽后刷新数据默认为true
const { plugin, onBeforeMove, filter, refresh = true, trigger } = this.dropConfig
this.rowSortable = plugin.create(this.$el.querySelector('.body__wrapper>.tiny-grid__body tbody'), {
handle: trigger || '.tiny-grid-body__row',
@ -36,12 +37,15 @@ export default {
this.$emit('row-drop-start', event, this)
},
onMove: (event) => {
let insertRecords = this.getInsertRecords()
const insertRecords = this.getInsertRecords()
// 包含新增数据的表格不可再拖动行顺序
if (insertRecords.length) return false
if (insertRecords.length) {
return false
}
let { dragged } = event
let selfRow = this.getRowNode(dragged).item
const { dragged } = event
// 获取被拖拽的行,这里在拖拽过程中被频繁触发,待优化
const selfRow = this.getRowNode(dragged).item
const cancel = typeof onBeforeMove === 'function' ? onBeforeMove('row', selfRow, event, this) : true
this.$emit('row-drop-move', event, this)

View File

@ -25,6 +25,7 @@
import { findTree } from '@opentiny/vue-renderless/grid/static/'
import Modal from '@opentiny/vue-modal'
import GlobalConfig from '../../config'
import { isVue2 } from '@opentiny/vue-common'
function handleIfScrollYLoadTruthy({ isScrollYLoad, _vm, selfRow, prevTrElem, targetTrElem }) {
if (!isScrollYLoad) {
@ -51,25 +52,27 @@ function handleIfScrollYLoadTruthy({ isScrollYLoad, _vm, selfRow, prevTrElem, ta
export const createHandlerOnEnd = ({ _vm, refresh }) => {
return (event) => {
let insertRecords = _vm.getInsertRecords()
const insertRecords = _vm.getInsertRecords()
// 包含新增数据的表格不可再拖动行顺序
if (insertRecords.length) return false
let options = { children: 'children' }
let targetTrElem = event.item
let { parentNode: wrapperElem, previousElementSibling: prevTrElem } = targetTrElem
let tableTreeData = _vm.data || _vm.tableData
let selfRow = _vm.getRowNode(targetTrElem).item
let selfNode = findTree(tableTreeData, (row) => row === selfRow, options)
let isScrollYLoad = _vm.scrollYLoad
if (insertRecords.length) {
return false
}
const options = { children: 'children' }
const targetTrElem = event.item
const { parentNode: wrapperElem, previousElementSibling: prevTrElem } = targetTrElem
// 这里优先使用用户通过props传递过来的表格数据所以拖拽后会改变原始数据
const tableTreeData = _vm.data || _vm.tableData
const selfRow = _vm.getRowNode(targetTrElem).item
const selfNode = findTree(tableTreeData, (row) => row === selfRow, options)
const isScrollYLoad = _vm.scrollYLoad
if (!isScrollYLoad) {
if (prevTrElem) {
// 移动到节点
let prevRow = _vm.getRowNode(prevTrElem).item
let prevNode = findTree(tableTreeData, (row) => row === prevRow, options)
const prevRow = _vm.getRowNode(prevTrElem).item
const prevNode = findTree(tableTreeData, (row) => row === prevRow, options)
if (findTree(selfRow[options.children], (row) => prevRow === row, options)) {
// 错误的移动
let oldTrElem = wrapperElem.children[event.oldIndex]
const oldTrElem = wrapperElem.children[event.oldIndex]
wrapperElem.insertBefore(targetTrElem, oldTrElem)
return Modal.message({
@ -78,7 +81,7 @@ export const createHandlerOnEnd = ({ _vm, refresh }) => {
})
}
let currRow = selfNode.items.splice(selfNode.index, 1)[0]
const currRow = selfNode.items.splice(selfNode.index, 1)[0]
if (_vm.hasTreeExpand(prevRow)) {
// 移动到当前的子节点
prevRow[options.children].splice(0, 0, currRow)
@ -89,7 +92,7 @@ export const createHandlerOnEnd = ({ _vm, refresh }) => {
}
} else {
// 移动到第一行
let currRow = selfNode.items.splice(selfNode.index, 1)[0]
const currRow = selfNode.items.splice(selfNode.index, 1)[0]
tableTreeData.unshift(currRow)
_vm.tableFullData = [].concat(tableTreeData)
}
@ -98,7 +101,8 @@ export const createHandlerOnEnd = ({ _vm, refresh }) => {
handleIfScrollYLoadTruthy({ isScrollYLoad, _vm, selfRow, prevTrElem, targetTrElem })
// 如果变动了树层级,需要刷新数据
_vm.$emit('row-drop-end', event, _vm, _vm.scrollYLoad ? tableTreeData : _vm.tableFullData)
refresh && _vm.data && _vm.refreshData()
// 因为vue2劫持了数组方法所以在data通过splice改变数组时数组长度不变会触发更新但是vue3是浅层响应所以需要通过传递数据让表格更新
refresh && _vm.data && !isVue2 && _vm.refreshData(_vm.data)
}
}

View File

@ -182,10 +182,10 @@ const Methods = {
}
return this.clearActived()
},
refreshData() {
let next = () => {
refreshData(data) {
const next = () => {
this.tableData = []
return this.loadTableData(this.tableFullData)
return this.loadTableData(data || this.tableFullData)
}
return this.$nextTick().then(next)
},
@ -233,7 +233,7 @@ const Methods = {
let { $refs, editStore, height, maxHeight } = this as any
let { lastScrollLeft, lastScrollTop } = this as any
let { scrollY } = this.optimizeOpts
// 原始全量数据
// 原始数据进行浅拷贝
let tableFullData = isArray(datas) ? datas.slice(0) : []
let scrollYLoad = scrollY && scrollY.gt > 0 && scrollY.gt <= tableFullData.length
@ -246,7 +246,7 @@ const Methods = {
// 原始数据
Object.assign(this, {
tableSynchData: datas,
// 此处存在性能问题,如果用户表格数据量很大,这里深拷贝会带来性能问题,
// 此处存在性能问题,如果用户表格数据量很大,这里深拷贝会带来性能问题
tableSourceData: clone(tableFullData, true),
scrollYLoad
})
@ -367,21 +367,22 @@ const Methods = {
fullColumnMap.set(column, colCache)
})
},
// 通过tr的dom元素获取行数据等相关信息
getRowNode(tr) {
if (!tr) {
return null
}
let { fullAllDataRowIdData, tableFullData, treeConfig } = this
let dataRowid = tr.getAttribute('data-rowid')
const { fullAllDataRowIdData, tableFullData, treeConfig } = this
const dataRowid = tr.getAttribute('data-rowid')
if (treeConfig) {
let matches = findTree(tableFullData, (row) => getRowid(this, row) === dataRowid, treeConfig)
const matches = findTree(tableFullData, (row) => getRowid(this, row) === dataRowid, treeConfig)
if (matches) {
return matches
}
} else {
if (fullAllDataRowIdData[dataRowid]) {
let rowCache = fullAllDataRowIdData[dataRowid]
const rowCache = fullAllDataRowIdData[dataRowid]
return {
item: rowCache.row,
index: rowCache.index,

View File

@ -46,6 +46,7 @@ const { SAAS: T_SAAS } = themes
const { DEFAULT: V_DEFAULT, CARD: V_CARD, LIST: V_LIST } = viewConfig
const { MF_SHOW_LIST: V_MF_LIST } = viewConfig
// 校验插件是否被注册
function verifyConfig(_vm) {
if (!getRowkey(_vm)) {
error('ui.grid.error.rowIdEmpty')
@ -509,7 +510,7 @@ const getTableData = () => {
elemStore: {},
// 表尾高度
footerHeight: 0,
// 缓存数据集
// 缓存数据集(键为rowid)
fullAllDataRowIdData: {},
fullAllDataRowMap: new Map(),
fullColumnIdData: {},