在 vue 里,如何把变量(props)自动传递下去?

2021-03-10 22:16:47 +08:00
 exc

有一个需求,做 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,如果可以这样,那么更好了,可以少写很多代码。

1309 次点击
所在节点    问与答
18 条回复
xingyue
2021-03-10 22:28:06 +08:00
看需求 mixin 应该很符合
https://cn.vuejs.org/v2/guide/mixins.html

不过个人建议还是插件
https://cn.vuejs.org/v2/guide/plugins.html
kikyous
2021-03-10 22:29:37 +08:00
inject/provider
szdubinbin
2021-03-10 22:31:11 +08:00
感觉你的描述很像 “inject”这个特征,
https://cn.vuejs.org/v2/api/#provide-inject

「这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。」
exc
2021-03-10 22:34:55 +08:00
@xingyue @kikyous @szdubinbin 感谢,这就去看看
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,
};
}
};
```
exc
2021-03-10 23:02:55 +08:00
@kikyous @szdubinbin inject/provider 可以免去在模板里申明一次的麻烦,但如何修改 provider 的数据呢?
cgpiao
2021-03-10 23:31:38 +08:00
emit 事件
exc
2021-03-10 23:38:59 +08:00
@xingyue mixin 在实例里更新数据后,组件不会响应,请问怎么办呢?测试如下: https://jsfiddle.net/Lzab481n/5/

点击 T 按钮后,`text-names` 组件不会响应
noe132
2021-03-10 23:55:55 +08:00
你 text-names 又没有 inject i18n,怎么可能会有响应
你 mixin 进来一个永远不会变的 getter,和你的 inject 一点关系都没有。
exc
2021-03-11 00:01:59 +08:00
@noe132 那应该怎么写呢?
noe132
2021-03-11 00:14:00 +08:00
provide 默认不是 reactive 的,所以需要 provide 一个 reactive 的对象
所有需要用到的地方写 inject
https://vuejs.org/v2/api/#provide-inject
https://jsfiddle.net/mLohkr94/5/
learningman
2021-03-11 00:14:44 +08:00
写个插件吧,官方的插件教程就是 i18n
zqx
2021-03-11 07:06:21 +08:00
直接在 main.js 的 vue 原型上注入吧
这样每个 vue 实例都可以通过 this.i18n 访问到你注入的数据
exc
2021-03-11 10:05:16 +08:00
@learningman 有链接吗,官方网站上没找到。。。
learningman
2021-03-11 10:21:34 +08:00
@exc https://cn.vuejs.org/v2/guide/plugins.html
老哥,官方教程啊。。。
exc
2021-03-11 12:09:24 +08:00
@learningman 官方的插件教程就是 i18n 。那个,这个,没看到 i18n 的示例呀,就几行代码,连一个完整的 demo 都没有。
learningman
2021-03-11 12:54:15 +08:00
exc
2021-03-11 13:42:22 +08:00
@learningman 非常感谢

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

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

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

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

© 2021 V2EX