vue-i18n:$tm无法解析指向对象/数组的链接键问题咨询
配置代码
messages: { en:{ itemSets:{ YesNoItems:[ {value:0, title:'No'}, {value:1, title:'Yes'}, ] }, Qs: { Q1: { label:'Title for Q1:' items : '@:itemSets.YesNoItems' } } } }
问题描述
我期望{{$tm('Qs.Q1.items')[1].title}}能显示'Yes',就像{{$tm('itemSets.YesNoItems')[1].title}}那样,但$tm似乎无法跟随@:链接键。
我知道可以移除Qs.Q1.items中的@:,使用{{$tm($t('Qs.Q1.items'))[1].title}},但这种方式无法体现该值是链接,也无法为其他不使用共享结构的Qs设置实际数组。
请问让$tm通过链接消息返回对象或数组,是否有我遗漏的语法?
解决方案
首先明确:$tm(即i18n的getMessage方法)本身不支持解析@:链接语法,这个语法是$t(translate方法)专属的解析逻辑,用来处理消息引用。
如果想保留@:的链接标识,同时让$tm能拿到对应的数组/对象,有两个可行的方案:
1. 自定义工具方法
写一个类似$linkedTm的方法,先调用$t解析链接得到目标键名,再把这个键名传给$tm获取原始对象/数组。
示例用法:{{$linkedTm('Qs.Q1.items')[1].title}},内部逻辑就是先执行$t('Qs.Q1.items')得到itemSets.YesNoItems,再用$tm获取这个键对应的数组。
2. 调整消息结构定义
把共享的数组/对象单独抽离,在Qs里直接引用键名而非用@:,但额外加个标识字段说明这是链接,比如:
messages: { en:{ itemSets:{ YesNoItems:[ {value:0, title:'No'}, {value:1, title:'Yes'}, ] }, Qs: { Q1: { label:'Title for Q1:' items: 'itemSets.YesNoItems', isLinked: true // 标识这是一个链接引用 }, Q2: { label:'Title for Q2:' items: [/* 自定义数组内容 */] } } } }
这样在模板里可以根据isLinked判断:如果是链接就用$tm($t('Qs.Q1.items')),否则直接用$tm('Qs.Q1.items'),既保留了链接标识,也支持自定义数组。
另外要注意:@:语法本质是字符串替换,$t会把@:itemSets.YesNoItems替换成该键对应的字符串化内容,但如果原始值是数组/对象,字符串化后就变成了[object Object]或者数组的字符串形式,根本没法直接用,所以$tm拿不到原始对象是必然的——因为@:处理后的结果已经不是原始的数组/对象了。
内容的提问来源于stack exchange,提问作者epeleg

