Skip to content

useManualRefHistory

类别
导出体积
518 B
上次更改
7 months ago
相关

手动跟踪 ref 的变化历史,当使用者调用 commit() 时,也提供了撤销和重做功能。

示例

Count: 0
/

历史记录(演示限制为 10 条记录)
2025-09-18 15:21:14{ value: 0 }

使用方法

ts
import { 
useManualRefHistory
} from '@vueuse/core'
import {
shallowRef
} from 'vue'
const
counter
=
shallowRef
(0)
const {
history
,
commit
,
undo
,
redo
} =
useManualRefHistory
(
counter
)
counter
.
value
+= 1
commit
()
console
.
log
(
history
.
value
)
/* [ { snapshot: 1, timestamp: 1601912898062 }, { snapshot: 0, timestamp: 1601912898061 } ] */

你可以使用 undo 将 ref 值重置为上一个历史点。

ts
console
.
log
(
counter
.
value
) // 1
undo
()
console
.
log
(
counter
.
value
) // 0

可变对象的历史记录

如果你要修改源对象,则需要传递一个自定义克隆函数或将 clone 参数设置为 true,它是一个最小克隆函数 x => JSON.parse(JSON.stringify(x)) 的快捷方式,它将在 dumpparse 中使用。

ts
import { 
useManualRefHistory
} from '@vueuse/core'
import {
ref
} from 'vue'
const
counter
=
ref
({
foo
: 1,
bar
: 2 })
const {
history
,
commit
,
undo
,
redo
} =
useManualRefHistory
(
counter
, {
clone
: true })
counter
.
value
.
foo
+= 1
commit
()

自定义克隆函数

要使用全功能或自定义克隆函数,你可以通过 clone 选项进行设置。

例如,使用 structuredClone

ts
import { 
useManualRefHistory
} from '@vueuse/core'
const
refHistory
=
useManualRefHistory
(target, {
clone
:
structuredClone
})

或者使用 lodash 的 cloneDeep

ts
import { 
useManualRefHistory
} from '@vueuse/core'
import {
cloneDeep
} from 'lodash-es'
const
refHistory
=
useManualRefHistory
(target, {
clone
:
cloneDeep
})

或者更轻量级的 klona

ts
import { 
useManualRefHistory
} from '@vueuse/core'
import {
klona
} from 'klona'
const
refHistory
=
useManualRefHistory
(target, {
clone
:
klona
})

自定义转储和解析函数

除了使用 clone 选项外,你还可以传递自定义函数来控制序列化和解析。如果你不需要历史值是对象,则在撤销时可以节省一个额外的克隆。如果你希望快照已经被字符串化以保存到本地存储中,这也很有用。

ts
import { 
useManualRefHistory
} from '@vueuse/core'
const
refHistory
=
useManualRefHistory
(target, {
dump
:
JSON
.
stringify
,
parse
:
JSON
.
parse
,
})

历史记录容量

默认情况下,我们会保留所有历史记录 (无限制),直到你明确清除它们,你可以通过 capacity 选项设置要保留的最大历史记录数量。

ts
import { 
useManualRefHistory
} from '@vueuse/core'
const
refHistory
=
useManualRefHistory
(target, {
capacity
: 15, // 限制为 15 条历史记录
})
refHistory
.
clear
() // 明确清除所有历史记录

类型声明

显示类型声明
ts
export interface 
UseRefHistoryRecord
<
T
> {
snapshot
:
T
timestamp
: number
} export interface
UseManualRefHistoryOptions
<
Raw
,
Serialized
=
Raw
> {
/** * 保留的历史记录的最大数量。默认为无限制。 */
capacity
?: number
/** * 在获取快照时进行克隆,快捷方式为 dump: JSON.parse(JSON.stringify(value))。 * 默认为 false * * @default false */
clone
?: boolean |
CloneFn
<
Raw
>
/** * 将数据序列化到历史记录中 */
dump
?: (
v
:
Raw
) =>
Serialized
/** * 从历史记录中反序列化数据 */
parse
?: (
v
:
Serialized
) =>
Raw
/** * 设置数据源 */
setSource
?: (
source
:
Ref
<
Raw
>,
v
:
Raw
) => void
} export interface
UseManualRefHistoryReturn
<
Raw
,
Serialized
> {
/** * 绕过跟踪的原始 ref */
source
:
Ref
<
Raw
>
/** * 用于撤销的历史记录数组,最新的记录在最前面 */
history
:
Ref
<
UseRefHistoryRecord
<
Serialized
>[]>
/** * 最后的历史记录点,如果暂停,则源可能不同 */
last
:
Ref
<
UseRefHistoryRecord
<
Serialized
>>
/** * 与 {@link UseManualRefHistoryReturn.history | history} 相同 */
undoStack
:
Ref
<
UseRefHistoryRecord
<
Serialized
>[]>
/** * 用于重做的记录数组 */
redoStack
:
Ref
<
UseRefHistoryRecord
<
Serialized
>[]>
/** * 表示是否可以撤销的 ref(undoStack 不为空) */
canUndo
:
ComputedRef
<boolean>
/** * 表示是否可以重做的 ref(redoStack 不为空) */
canRedo
:
ComputedRef
<boolean>
/** * 撤销更改 */
undo
: () => void
/** * 重做更改 */
redo
: () => void
/** * 清除所有历史记录 */
clear
: () => void
/** * 创建新的历史记录 */
commit
: () => void
/** * 使用最新历史记录重置 ref 的值 */
reset
: () => void
} /** * Track the change history of a ref, also provides undo and redo functionality. * * @see https://vueuse.org/useManualRefHistory * @param source * @param options */ export declare function
useManualRefHistory
<
Raw
,
Serialized
=
Raw
>(
source
:
Ref
<
Raw
>,
options
?:
UseManualRefHistoryOptions
<
Raw
,
Serialized
>,
):
UseManualRefHistoryReturn
<
Raw
,
Serialized
>

源码

源码演示文档

贡献者

Anthony Fu
一纸忘忧
Matias Capeletto
Anthony Fu
SerKo
Robin
IlyaL
trent
Lov`u`e
Егор
丶远方
azaleta
Eduardo Wesley
Sahin D
vaakian X
Hollis Wu
wheat
Alex Kozack

更新日志

0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
b46d2 - fix: canUndo and canRedo typing to be computed ref (#4261)