[Bug] 自定义排序,或自定义筛选的状态下,进行编辑表格内容后,筛选的结果被重置了。
Open
Nobody has claimed this yet.
bug
- Dominant language
- TypeScript
- Stars
- 3.7k
- Forks
- 486
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 16
Description
Version
1.19.3
Link to Minimal Reproduction
页面代码在重现步骤中
Steps to Reproduce
<style>
.sortClass {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.header-title {
width: 100%;
display: flex;
justify-content: space-between;
}
.vtable-list1.sort-caret {
width: 0;
height: 0;
border: solid 5px transparent;
position: absolute;
left: 7px;
}
.vtable-list1 .sort-caret.ascending {
border-bottom-color: var(--el-text-color-placeholder);
top: -5px;
}
.vtable-list1 .caret-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 24px;
justify-items: flex-start;
cursor: pointer;
overflow: initial;
position: relative;
}
</style>
<template>
<div :style="{ height: '100%', width: '100%' }" class="vtable-list1">
<ListTable :options="option" :records="records" ref="tableRef">
<!-- Order Number Column -->
<ListColumn
:field="item.field"
:title="item.title"
v-for="(item, index) in columns"
:key="item.field"
:width="item.width"
:aggregation="item.aggregation"
editor="input-editor"
>
<template
v-if="item.field"
#headerCustomLayout="{ table, row, col, rect, record, width, height }"
>
<Group
:height="height"
:width="width"
display="flex"
flexDirection="row"
flexWrap="nowrap"
:vue="{}"
>
<div class="bloggerName" style="pointer-events: all">
<div v-if="item.field != 'index'" class="header-title">
<div>{{ item.title }}</div>
<span class="caret-wrapper">
<el-icon v-if="item.sortType == 'normal'" @click="sortClick('desc', item.field)"
><DCaret
/></el-icon>
<el-icon v-if="item.sortType == 'desc'" @click="sortClick('aesc', item.field)"
><CaretTop color="#409eff"
/></el-icon>
<el-icon v-if="item.sortType == 'aesc'" @click="sortClick('normal', item.field)"
><CaretBottom color="#409eff"
/></el-icon>
</span>
</div>
<input
v-model="form[item.field]"
placeholder="搜索内容"
@change="(e) => handInputChange(e, item.field)"
style="width: 100%; border: 1px solid; margin: 2px"
/>
</div>
</Group>
</template>
</ListColumn>
</ListTable>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { ListTable, ListColumn, register } from '@visactor/vue-vtable'
import { Group, Text, Image, Radio, CheckBox, Tag } from '@visactor/vue-vtable'
import { DateInputEditor, InputEditor, ListEditor, TextAreaEditor } from '@visactor/vtable-editors'
import * as VTable from '@visactor/vtable'
const tableRef = ref()
const percentCalc = VTable.CustomLayout.percentCalc
const columns = [
{
type: 'text',
title: '产品名称',
field: 'productName',
width: '150px',
sortType: 'normal',
aggregation: {
aggregationType: VTable.TYPES.AggregationType.NONE,
formatFun(value) {
return '总计:'
},
},
},
{ type: 'text', title: '单片名称', field: 'pieceName', width: '150px', sortType: 'normal' },
{ type: 'numeric', title: '宽', field: 'width', width: '120px', sortType: 'normal' },
{ type: 'numeric', title: '高', field: 'height', width: '120px', sortType: 'normal' },
{
type: 'numeric',
title: '数量',
field: 'num',
width: '120px',
sortType: 'normal',
aggregation: {
aggregationType: VTable.TYPES.AggregationType.SUM,
formatFun(value) {
return value
},
},
}]
const form = reactive({})
onMounted(() => {
window.top.postMessage(
{
at: 'dd',
type: 'childMounted',
data: {
data: [],
},
},
'*',
)
tableRef.value.vTableInstance.on('change_cell_value', changeEditCell)
tableRef.value.vTableInstance.on('dblclick_cell', dblclickCellClick)
tableRef.value.vTableInstance.on('dropdown_menu_click', dropclickCellClick)
function dropclickCellClick(args) {
let tableInstance = tableRef.value.vTableInstance
if (args.menuKey === '向上插入空行') {
const recordIndex = tableInstance.getRecordShowIndexByCell(args.col, args.row)
if (recordIndex) {
tableInstance.addRecord({}, recordIndex - 1)
} else {
tableInstance.addRecord({}, 0)
}
} else if (args.menuKey === '向下插入空行') {
const recordIndex = tableInstance.getRecordShowIndexByCell(args.col, args.row)
tableInstance.addRecord({}, recordIndex + 1)
} else if (args.menuKey === '删除该行') {
const recordIndex = tableInstance.getRecordShowIndexByCell(args.col, args.row)
tableInstance.deleteRecords([recordIndex])
}
}
function changeEditCell() {
console.log('changeEditCell')
}
function dblclickCellClick(data) {
if (data.row) {
// Object.keys(form).forEach((key) => {
// form[key] = ''
// })
}
}
function sortClick(action, id) {
columns.forEach((value, index) => {
if (value.field == id) {
value.sortType = action
} else {
value.sortType = 'normal'
}
})
if (!action) return
tableRef.value.vTableInstance.updateSortState({
field: id,
order: action,
})
tableRef.value.vTableInstance.renderWithRecreateCells()
}
function handInputChange(e, type) {
tableRef.value.vTableInstance.updateFilterRules([
{
filterFunc: (record) => {
// console.log(form, 'form')
// Object.keys(form).forEach((key) => {
// console.log(key, 'key')
// if (key != type) {
// form[key] = ''
// }
// })
// if (!record) return
return String(record[type]).includes(form[type])
},
},
])
}
let records = ref([{ productName: '234234' }, { productName: '234234' }, { productName: '234234' }])
const inputEditor = new InputEditor()
const textAreaEditor = new TextAreaEditor()
const dateInputEditor = new DateInputEditor()
register.editor('input-editor', inputEditor)
const option = {
defaultRowHeight: 80,
// defaultColWidth:160,
defaultHeaderRowHeight: 80,
containerFit: {
width: true,
height: true,
},
customConfig: {
createReactContainer: true,
},
keyboardOptions: {
moveEditCellOnArrowKeys: true,
copySelected: true,
pasteValueToCell: true,
},
dragOrder: {
dragHeaderMode: 'column',
},
widthMode: 'standard',
bottomFrozenRowCount: 1,
emptyTip: {
text: '无数据',
},
menu: {
contextMenuItems: ['向上插入空行', '向下插入空行', '删除该行'],
},
rowSeriesNumber: {
title: '序号',
width: 'auto',
headerStyle: {
color: 'black',
bgColor: '',
},
style: {
color: 'black',
},
},
}
</script>
<style>
.bloggerName {
/* width: 330px;; */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>
Current Behavior
搜索筛选后,编辑单元格后,全量数据会立即重置
例如:筛选出一条数据,编辑状态下,编辑后,数据会被立即重置成3条数据。
Expected Behavior
搜索筛选后,编辑单元格后,数据条数不应变化
例如:筛选出一条数据,编辑状态下,编辑后,数据保持1条
Environment
- OS:macOS Monterey
- Browser:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0
- Framework:Vue@3.5.17
Any additional comments?
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Vue reproduction in the issue and reproduce the sequence of applying updateFilterRules, editing a cell through input-editor, and observing the change_cell_value event. Trace how filtering and editing interact after the edit. Done means the filtered result remains unchanged after editing, such as one visible row remaining when one row matched before the edit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100