请问 vue 的 defineEmits 类型如何使用动态键名

3 天前
 waiaan
enum BaseEvent {
  CLICK = 'click'
}

interface CustomEvent{
  [BaseEvent.CLICK]:string
}

defineEmits<EmitEvents>()

上面这种写法 @vue/compiler-sfc 会报 Unsupported computed key in type referenced by a macro ,应该怎么写才对?谢谢。

984 次点击
所在节点    Vue.js
4 条回复
murmur
3 天前
换个思路,事件是双参数,第一个参数是你真的事件名字,后面是 args
dssxzuxc
3 天前
应该实现不了,defineXxxx 是编译器宏,会在编译阶段把 setup/props/emits/model 等展开转换成更低级的写法,如果是 TypeScript ,会在这个阶段进行类型检查并生成对应的运行时值。
为了能在编译阶段做这件事,类型必须是静态的(虽然后面开始支持泛型了),不然编译器毛都找不到怎么给你转换成运行时值。
另外建议不要在 Typescritp 用 enum ,绝大多数场景
'a' | 'b' | 'c' 比
enum BaseEvent {
a = 'a',
b = 'b',
c = 'c',
} 更好,还省去了一堆 import
枚举唯一的好处就是改名不用重构,但这玩意谁没事会去改,经手过几个项目都是枚举用得飞起,我自己写的就完全不用。

又试了下
type Test = 'a' | 'b' | 'c'
type CustomEvent = {
[K in Test]: string
}
defineEmits<CustomEvent>()
这样写是不会有警告的,说明编译器在编译阶段确实拿到了三个字面量,顺利生成代码。不过我懒得检查是否功能正常了,我不会写这种玩意,而且 eslint 会警告要改成 Record ,Record 写法无法通过编译。
vitar
3 天前
ts 配置现代搞得一点,启用 erasableSyntaxOnly 。不用 enum 就没问题了
unhappy224
1 天前
const BaseEvent {
CLICK : 'click'
} as const

试试这样呢?不过这样也算不上动态吧
运行时动态也没啥意义,本来就是方便开发的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1155847

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX