有许多模式可以用来改进你的组合式函数(composables)。 使用对象来传递参数是一种非常有用的模式,在很多地方都有使用 --- 只需看看 VueUse 的源码就知道了。 但是,虽然这种模式乍看起来很简单,在实现时还是有一些需要考虑的事项:
-
当你有很多选项时会发生什么?真的很多?
-
当你只有几个选项时该怎么办?
-
如何判断你是否在错误地使用这种模式?
在本文中,我们将探讨 Options Object 模式。我们将介绍实现的基础知识,然后转向高级用例以及权衡使用它时的利弊。
该模式如何工作
为了使我们的代码更具可重用性,我们需要它能覆盖广泛的情况。 我们通过传入一个包含所有配置选项的对象来实现这一点,这些选项决定了我们希望组合式函数如何表现:
go
const state = ref({ email: '' });
const { history, undo, redo } = useRefHistory(state, {
// 递归跟踪历史
deep: true,
// 限制我们保存的变更数量
capacity: 10,
});
我们在这里使用对象而不是一长串参数:
go
const { history, undo, redo } = useRefHistory(state, true, 10));
使用选项对象而不是参数给我们带来了几个好处。
首先,它是自文档化的。我们在值旁边直接有参数的名称,所以我们永远不会忘记每个值的作用。 我们还可以为整个选项对象创建一个类型:
go
export type RefHistoryOptions {
deep?: boolean;
capacity?: number;
};
export type RefHistoryReturn {
history: Ref;
undo: () => void;
redo: () => void;
};
export function useRefHistory(
ref: Ref,
options: RefHistoryOptions
): RefHistoryReturn {};
其次,我们不需要担心顺序或未使用的选项。我们用组合式函数覆盖的潜在边缘情况越多,就会有越多的选项。但我们通常只需要一次关注其中的几个 --- 它们都是可选的。
第三,添加新选项变得更加容易。因为顺序无关紧要,并且没有任何选项是必需的,所以向我们的组合式函数添加新功能不会破坏任何东西。我们只需将它添加到可能的选项列表中并继续前进。
实现该模式
实现这个模式也不需要太多工作:
go
export function useRefHistory(ref, options) {
const {
deep = false,
capacity = Infinity,
} = options;
// ...
};
首先,我们将选项对象作为最后一个参数传入。这使得选项对象本身成为一个可选参数成为可能。
必需的参数排在前面。通常,只会有一两个。更多的参数是代码异味,很可能意味着你的组合式函数试图做太多事情。
必需的参数(或参数们)通常是一个 Ref,或者如果我们也在实现灵活参数模式,则是一个 MaybeRef。