【问题标题】:Why is type of computed property Ref<readonly string[]>?为什么计算属性的类型是 Ref<readonly string[]>?
【发布时间】:2020-04-10 09:55:08
【问题描述】:
type Items = string[]
const list = ref<Items>([])
const items = computed({
get: () => list.value,
set: (items: Items) => {
list.value = items
},
})
这是我使用 setter 计算的属性。我的问题是:为什么我在提供 setter 时返回了 Ref<readonly string[]>?我希望项目的类型为Ref<string[]>
【问题讨论】:
标签:
vue.js
vue-composition-api
【解决方案1】:
The documentation 对 computed 类型不精确(它提到 Ref<T> 而不是 Ref<Readonly<T>>)但解释了只读和可变计算属性之间的区别:
接受一个 getter 函数并为 getter 的返回值返回一个不可变的响应式 ref 对象。
或者,它可以使用具有 get 和 set 函数的对象来创建可写的 ref 对象。
真正的类型是:
export declare function computed<T>(getter: Option<T>['get']): Readonly<Ref<Readonly<T>>>;
export declare function computed<T>(options: Option<T>): Ref<Readonly<T>>;
Ref<Readonly<string[]>> 类型意味着 ref 值可以像 ref.value = items 一样重新分配,但不能像 ref.value[0] = item 那样发生突变。
【解决方案2】:
对于这种情况,您应该使用WritableComputedRef<T>,因为当我们只使用ComputedRef 时,它只用于读取,而不用于写入。
例如
let showMenu: WritableComputedRef<boolean> = computed({
get: () => props.show,
set: (value: boolean) => {
ctx.emit("update:show", value);
},
});
const handleEscape = (e: KeyboardEvent): void => {
if (e.key === "Esc" || e.key === "Escape") {
showMenu.value = false;
}
};