TanStack Table 具有一个简单的底层内部状态管理系统,用于存储和管理表格的状态。它还允许您选择性地提取您需要在自己的状态管理中管理的任何状态。本指南将引导您了解与表格状态交互和管理的不同方式。
您无需进行任何特殊设置即可使表格状态工作。如果您没有向 state、initialState 或任何 on[State]Change 表格选项传递任何内容,则表格将在内部管理其自身的状态。您可以使用 table.getState() 表格实例 API 访问此内部状态的任何部分。
const table = useVueTable({
columns,
data: dataRef, // Reactive data support
//...
})
console.log(table.getState()) //access the entire internal state
console.log(table.getState().rowSelection) //access just the row selection state
const table = useVueTable({
columns,
data: dataRef, // Reactive data support
//...
})
console.log(table.getState()) //access the entire internal state
console.log(table.getState().rowSelection) //access just the row selection state
v8.20.0 版本新增
useVueTable Hook 现在支持响应式数据。这意味着您可以将包含您的数据的 Vue ref 或 computed 传递给 data 选项。表格将自动对数据中的更改做出反应。
const columns = [
{ accessor: 'id', Header: 'ID' },
{ accessor: 'name', Header: 'Name' }
]
const dataRef = ref([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
])
const table = useVueTable({
columns,
data: dataRef, // Pass the reactive data ref
})
// Later, updating dataRef will automatically update the table
dataRef.value = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Doe' }
]
const columns = [
{ accessor: 'id', Header: 'ID' },
{ accessor: 'name', Header: 'Name' }
]
const dataRef = ref([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
])
const table = useVueTable({
columns,
data: dataRef, // Pass the reactive data ref
})
// Later, updating dataRef will automatically update the table
dataRef.value = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Doe' }
]
⚠️ shallowRef 在底层出于性能原因而被使用,这意味着数据不是深度响应式的,只有 .value 是。要更新数据,您必须直接修改数据。
const dataRef = ref([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
])
// This will NOT update the table ❌
dataRef.value.push({ id: 4, name: 'John' })
// This will update the table ✅
dataRef.value = [
...dataRef.value,
{ id: 4, name: 'John' }
]
const dataRef = ref([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
])
// This will NOT update the table ❌
dataRef.value.push({ id: 4, name: 'John' })
// This will update the table ✅
dataRef.value = [
...dataRef.value,
{ id: 4, name: 'John' }
]
如果您对某些状态所需要做的只是自定义其初始默认值,则仍然不需要自己管理任何状态。您只需在表格实例的 initialState 选项中设置值即可。
const table = useVueTable({
columns,
data,
initialState: {
columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
columnVisibility: {
id: false //hide the id column by default
},
expanded: true, //expand all rows by default
sorting: [
{
id: 'age',
desc: true //sort by age in descending order by default
}
]
},
//...
})
const table = useVueTable({
columns,
data,
initialState: {
columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
columnVisibility: {
id: false //hide the id column by default
},
expanded: true, //expand all rows by default
sorting: [
{
id: 'age',
desc: true //sort by age in descending order by default
}
]
},
//...
})
注意:仅在 initialState 或 state 中指定每个特定状态,但不要两者都指定。如果您将特定的状态值同时传递给 initialState 和 state,则 state 中初始化的状态将覆盖 initialState 中的任何对应值。
如果您需要在应用程序的其他区域轻松访问表格状态,TanStack Table 可以让您轻松地在自己的状态管理系统中控制和管理任何或全部表格状态。您可以通过将您自己的状态和状态管理函数传递给 state 和 on[State]Change 表格选项来做到这一点。
您可以只控制您需要轻松访问的状态。如果您不需要,则不必控制所有表格状态。建议仅根据具体情况控制您所需的状态。
为了控制特定状态,您需要同时将相应的 state 值和 on[State]Change 函数传递给表格实例。
让我们以“手动”服务器端数据获取场景中的筛选、排序和分页为例。您可以将筛选、排序和分页状态存储在您自己的状态管理中,但如果您的 API 不关心这些值,则可以忽略任何其他状态,例如列顺序、列可见性等。
const columnFilters = ref([]) //no default filters
const sorting = ref([{
id: 'age',
desc: true, //sort by age in descending order by default
}])
const pagination = ref({ pageIndex: 0, pageSize: 15 }
//Use our controlled state values to fetch data
const tableQuery = useQuery({
queryKey: ['users', columnFilters, sorting, pagination],
queryFn: () => fetchUsers(columnFilters, sorting, pagination),
//...
})
const table = useVueTable({
columns,
data: tableQuery.data,
//...
state: {
get columnFilters() {
return columnFilters.value
},
get sorting() {
return sorting.value
},
get pagination() {
return pagination.value
}
},
onColumnFiltersChange: updater => {
columnFilters.value =
updater instanceof Function
? updater(columnFilters.value)
: updater
},
onSortingChange: updater => {
sorting.value =
updater instanceof Function
? updater(sorting.value)
: updater
},
onPaginationChange: updater => {
pagination.value =
updater instanceof Function
? updater(pagination.value)
: updater
},
})
//...
const columnFilters = ref([]) //no default filters
const sorting = ref([{
id: 'age',
desc: true, //sort by age in descending order by default
}])
const pagination = ref({ pageIndex: 0, pageSize: 15 }
//Use our controlled state values to fetch data
const tableQuery = useQuery({
queryKey: ['users', columnFilters, sorting, pagination],
queryFn: () => fetchUsers(columnFilters, sorting, pagination),
//...
})
const table = useVueTable({
columns,
data: tableQuery.data,
//...
state: {
get columnFilters() {
return columnFilters.value
},
get sorting() {
return sorting.value
},
get pagination() {
return pagination.value
}
},
onColumnFiltersChange: updater => {
columnFilters.value =
updater instanceof Function
? updater(columnFilters.value)
: updater
},
onSortingChange: updater => {
sorting.value =
updater instanceof Function
? updater(sorting.value)
: updater
},
onPaginationChange: updater => {
pagination.value =
updater instanceof Function
? updater(pagination.value)
: updater
},
})
//...
或者,您可以使用 onStateChange 表格选项控制整个表格状态。它会将整个表格状态提升到您自己的状态管理系统中。请注意这种方法,因为您可能会发现将一些频繁更改的状态值(如 columnSizingInfo 状态)提升到 React 树中可能会导致糟糕的性能问题。
可能需要一些额外的技巧才能使其工作。如果您使用 onStateChange 表格选项,则 state 的初始值必须填充您要使用的所有功能的所有相关状态值。您可以手动键入所有初始状态值,或者以如下所示的特殊方式使用 table.setOptions API。
//create a table instance with default state values
const table = useVueTable({
get columns() {
return columns.value
},
data,
//... Note: `state` values are NOT passed in yet
})
const state = ref({
...table.initialState,
pagination: {
pageIndex: 0,
pageSize: 15
}
})
const setState = updater => {
state.value = updater instanceof Function ? updater(state.value) : updater
}
//Use the table.setOptions API to merge our fully controlled state onto the table instance
table.setOptions(prev => ({
...prev, //preserve any other options that we have set up above
get state() {
return state.value
},
onStateChange: setState //any state changes will be pushed up to our own state management
}))
//create a table instance with default state values
const table = useVueTable({
get columns() {
return columns.value
},
data,
//... Note: `state` values are NOT passed in yet
})
const state = ref({
...table.initialState,
pagination: {
pageIndex: 0,
pageSize: 15
}
})
const setState = updater => {
state.value = updater instanceof Function ? updater(state.value) : updater
}
//Use the table.setOptions API to merge our fully controlled state onto the table instance
table.setOptions(prev => ({
...prev, //preserve any other options that we have set up above
get state() {
return state.value
},
onStateChange: setState //any state changes will be pushed up to our own state management
}))
到目前为止,我们已经看到了 on[State]Change 和 onStateChange 表格选项如何将表格状态更改“提升”到我们自己的状态管理中。但是,关于使用这些选项,您应该注意一些事项。
指定 on[State]Change 回调会告诉表格实例这将是一个受控状态。如果您未指定相应的 state 值,则该状态将“冻结”为其初始值。
const sorting = ref([])
const setSorting = updater => {
sorting.value = updater instanceof Function ? updater(sorting.value) : updater
}
//...
const table = useVueTable({
columns,
data,
//...
state: {
get sorting() {
return sorting //required because we are using `onSortingChange`
},
},
onSortingChange: setSorting, //makes the `state.sorting` controlled
})
const sorting = ref([])
const setSorting = updater => {
sorting.value = updater instanceof Function ? updater(sorting.value) : updater
}
//...
const table = useVueTable({
columns,
data,
//...
state: {
get sorting() {
return sorting //required because we are using `onSortingChange`
},
},
onSortingChange: setSorting, //makes the `state.sorting` controlled
})
on[State]Change 和 onStateChange 回调的工作方式与 React 中的 setState 函数完全相同。更新器值可以是新的状态值,也可以是接受先前的状态值并返回新的状态值的回调函数。
这有什么含义?这意味着,如果您想在任何 on[State]Change 回调中添加一些额外的逻辑,您可以这样做,但是您需要检查新的传入更新器值是函数还是值。
这就是为什么我们在上面的 setState 函数中进行了 updater instanceof Function 检查。此检查使我们能够在同一函数中处理原始值和回调函数。
TanStack Table 中的所有复杂状态都有自己的 TypeScript 类型,您可以导入和使用。这对于确保您为正在控制的状态值使用正确的数据结构和属性非常有用。
import { useVueTable, type SortingState } from '@tanstack/vue-table'
//...
const sorting = ref<SortingState[]>([
{
id: 'age', //you should get autocomplete for the `id` and `desc` properties
desc: true,
}
])
import { useVueTable, type SortingState } from '@tanstack/vue-table'
//...
const sorting = ref<SortingState[]>([
{
id: 'age', //you should get autocomplete for the `id` and `desc` properties
desc: true,
}
])
您的每周 JavaScript 新闻。每周一免费发送给超过 100,000 名开发者。