typescript - 有什么办法可以同时使用 ES6 私有字段和 Vue 3 的 `reactive`?
问题描述
我有一个使用 ES6 私有字段和公共 getter 的类,我需要使用 Vue 3 的组合 API 进行反应。目前,我的设置如下所示:
//store.ts
class Store {
#userName?: string
get userName() {
if(this.#userName !== undefined) return this.#userName
throw new Error('Cannot get userName before it is defined')
}
setUserName(newUserName: string) {
this.#userName = newUserName
}
}
const store = reactive(new Store())
export { store }
然后通过提供/注入 API 将此存储实例提供给组件,并像这样使用
<template>
<span> {{ formattedUserName }} </span>
</template>
<script lang="ts">
import { defineComponent, toRefs, inject } from 'vue'
export default defineComponent({
setup(){
const store = inject('storeKey')
const formattedUserName = doSomeThings(store.userName)
return { formattedUserName }
})
但是当我尝试这样做时,我得到了这个错误:
Cannot read private member #userName from an object whose class did not declare it
有人可以解释为什么会这样,如果有办法解决吗?我知道 TypeScript 有private
关键字,但如果可能的话,我想使用私有字段,因为它们实际上在运行时强制执行隐私。
谢谢!
编辑:经过更多研究,我找到了问题“为什么”部分的答案。Vue 3 使用代理来跟踪反应性,不幸的是它不适用于私有字段。如果有任何方法可以解决这个问题,我仍然很想知道。
解决方案
如此简短的回答:没有简单的方法仍然可以同时使用私有字段和代理。现在(2021 年 8 月 10 日)实施的私有字段和代理从根本上不兼容。我原始帖子中的第二个链接对为什么会这样以及是否应该更改进行了大量讨论,但是如果没有新的提议,看起来事情就是这样。
这就是我如何建立一家商店的方法
- 为其成员编译时间隐私
- 那些保证返回值不是未定义的成员的反应性、只读(也在编译时)getter
- 也可能有副作用的特定设置器
import {ref, reactive, computed} from 'vue'
class Store {
private internal_userName: Ref<string | undefined> = ref(undefined)
readonly userName = computed((): string => {
if(this.internal_userName.value !== undefined) return this.internal_userName.value
throw new Error('Cannot access userName before it is defined')
})
setUserName(newUserName: string) {
// do side effects here, such as setting localStorage keys
this.internal_userName.value = newUserName
}
}
const store = reactive(new Store())
//do things to export or provide your store here
推荐阅读
- python - 当另一列增加/减少时添加状态列
- go - 从休息层的 POST 请求中排除 ID(自动增量)
- python-3.x - 如何在一个数据框中合并两列(同名)?熊猫,蟒蛇
- unicode - NSIS nsProcess 插件:始终返回“进程未运行”
- java - 静态快捷方式android不出现
- java - Apache Camel:如何查看正文以确定文件格式
- video - 索引数据包中的大型视频数据文件
- oracle - oracle 中热门查询的自动 SQL 调优顾问报告
- javascript - 如何在 NODE.JS 中保存标头?
- postgresql - pg_dump - 名称中带有特殊字符的转储模式