useManualRefHistory
手动跟踪 ref 的变化历史,当使用者调用 commit()
时,也提供了撤销和重做功能。
Demo
使用方法
ts
import { useManualRefHistory } from '@vueuse/core'
import { ref } from 'vue'
const counter = ref(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))
的快捷方式,它将在 dump
和 parse
中使用。
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
const refHistory = useManualRefHistory(target, {
capacity: 15, // 限制为 15 条历史记录
})
refHistory.clear() // 明确清除所有历史记录
类型声明
显示类型声明
typescript
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>
Source
贡献者
Anthony Fu
丶远方
Matias Capeletto
trent
Anthony Fu
Lov`u`e
Егор
azaleta
Eduardo Wesley
Sahin D
vaakian X
Hollis Wu
wheat
Alex Kozack
变更日志
v11.2.0
on 10/30/2024v10.0.0-beta.5
on 4/13/2023cb644
- refactor!: remove isFunction
and isString
utils