有一个需求,做 i18n 国际化,网上看的诸多方案不太喜欢(都要在模板里调用一个翻译函数),于是捣鼓了一种方式:
让 vue app 实例持有一份 i18n 清单,并通过 props 传递给每个实例或组件,这样每个实例都能使用这个 i18n 对象了。
不过这种写法还是比较丑陋的,因为传递的方式是这样的,且每个地方都要写一遍:
<router-view v-bind:i18n="i18n" class="view"></router-view>
必须要显式的把 i18n 传递给 router-view
,我希望这一步能够自动完成,即写的时候不用写 v-bind:i18n="i18n"
:
<router-view class="view"></router-view>
不知道 vue 支持不支持这种操作,怎么做?
题外话,vue 有没有一种方式,让组件访问上级实例的数据?就是说我不把 i18n 通过 props 传递给组件,组件(模板)也能访问 i18n,如果可以这样,那么更好了,可以少写很多代码。
1
xingyue 2021-03-10 22:28:06 +08:00 via Android 1
看需求 mixin 应该很符合
https://cn.vuejs.org/v2/guide/mixins.html 不过个人建议还是插件 https://cn.vuejs.org/v2/guide/plugins.html |
2
kikyous 2021-03-10 22:29:37 +08:00 via Android 2
inject/provider
|
3
szdubinbin 2021-03-10 22:31:11 +08:00 1
感觉你的描述很像 “inject”这个特征,
https://cn.vuejs.org/v2/api/#provide-inject 「这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。」 |
4
exc OP |
5
Shook 2021-03-10 22:44:49 +08:00
i18n.js:
``` import { inject } from 'vue'; function i18n() { console.log('hello'); } const globalKey = 'i18n'; export function install(app) { app.provide(globalKey, i18n); } export function useI18n() { return inject(globalKey); } export default { install }; ``` main.js: ``` import { createApp } from 'vue'; import App from './app.jsx'; const app = createApp(App); import i18n from 'i18n.js'; app.use(i18n); app.mount('#app'); ``` Child: ``` import { useI18n } from 'xxx'; export { setup() { const i18n = useI18n(); i18n(); // hello return { i18n, }; } }; ``` |
6
exc OP @kikyous @szdubinbin inject/provider 可以免去在模板里申明一次的麻烦,但如何修改 provider 的数据呢?
|
7
cgpiao 2021-03-10 23:31:38 +08:00 via iPhone
emit 事件
|
8
exc OP @xingyue mixin 在实例里更新数据后,组件不会响应,请问怎么办呢?测试如下: https://jsfiddle.net/Lzab481n/5/
点击 T 按钮后,`text-names` 组件不会响应 |
9
noe132 2021-03-10 23:55:55 +08:00
你 text-names 又没有 inject i18n,怎么可能会有响应
你 mixin 进来一个永远不会变的 getter,和你的 inject 一点关系都没有。 |
11
noe132 2021-03-11 00:14:00 +08:00 1
provide 默认不是 reactive 的,所以需要 provide 一个 reactive 的对象
所有需要用到的地方写 inject https://vuejs.org/v2/api/#provide-inject https://jsfiddle.net/mLohkr94/5/ |
12
learningman 2021-03-11 00:14:44 +08:00 via Android
写个插件吧,官方的插件教程就是 i18n
|
13
zqx 2021-03-11 07:06:21 +08:00 via Android
直接在 main.js 的 vue 原型上注入吧
这样每个 vue 实例都可以通过 this.i18n 访问到你注入的数据 |
14
exc OP @learningman 有链接吗,官方网站上没找到。。。
|
15
learningman 2021-03-11 10:21:34 +08:00 via Android
|
16
exc OP @learningman 官方的插件教程就是 i18n 。那个,这个,没看到 i18n 的示例呀,就几行代码,连一个完整的 demo 都没有。
|
17
learningman 2021-03-11 12:54:15 +08:00 1
|
18
exc OP @learningman 非常感谢
|