在 vue 里,如何把变量(props)自动传递下去? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
exc
V2EX    问与答

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

  •  
  •   exc 2021-03-10 22:16:47 +08:00 1814 次点击
    这是一个创建于 1755 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个需求,做 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 条附言    2021-03-10 23:05:33 +08:00
    经楼下提示,使用 provide / inject 可以向所有下级组件注入数据,但如何修改 provide 的数据呢?下面链接是一个测试(点击 T 按钮切换语言),使用 props 的组件可以正常工作,使用 provide/inject 的则不能。

    https://jsfiddle.net/Lzab481n/4/
    第 2 条附言    2021-03-11 10:07:15 +08:00
    谢谢大家的回复,#11 @noe132 给的答案已经解决了我的问题,参考 demo: https://jsfiddle.net/mLohkr94/5/
    第 3 条附言    2021-03-11 18:25:48 +08:00
    经试验,感觉插件更符合我的需求,也更简洁,代码如下: https://jsfiddle.net/72mh01ry/

    可以和上一个 append 对比,感谢 @xingyue @learningman
    18 条回复    2021-03-11 13:42:22 +08:00
    xingyue
        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
    kikyous
        2
    kikyous  
       2021-03-10 22:29:37 +08:00 via Android   2
    inject/provider
    szdubinbin
        3
    szdubinbin  
       2021-03-10 22:31:11 +08:00   1
    感觉你的描述很像 “inject”这个特征,
    https://cn.vuejs.org/v2/api/#provide-inject

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

    点击 T 按钮后,`text-names` 组件不会响应
    noe132
        9
    noe132  
       2021-03-10 23:55:55 +08:00
    你 text-names 又没有 inject i18n,怎么可能会有响应
    你 mixin 进来一个永远不会变的 getter,和你的 inject 一点关系都没有。
    exc
        10
    exc  
    OP
       2021-03-11 00:01:59 +08:00
    @noe132 那应该怎么写呢?
    noe132
        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/
    learningman
        12
    learningman  
       2021-03-11 00:14:44 +08:00 via Android
    写个插件吧,官方的插件教程就是 i18n
    zqx
        13
    zqx  
       2021-03-11 07:06:21 +08:00 via Android
    直接在 main.js 的 vue 原型上注入吧
    这样每个 vue 实例都可以通过 this.i18n 访问到你注入的数据
    exc
        14
    exc  
    OP
       2021-03-11 10:05:16 +08:00
    @learningman 有链接吗,官方网站上没找到。。。
    learningman
        15
    learningman  
       2021-03-11 10:21:34 +08:00 via Android
    @exc https://cn.vuejs.org/v2/guide/plugins.html
    老哥,官方教程啊。。。
    exc
        16
    exc  
    OP
       2021-03-11 12:09:24 +08:00
    @learningman 官方的插件教程就是 i18n 。那个,这个,没看到 i18n 的示例呀,就几行代码,连一个完整的 demo 都没有。
    exc
        18
    exc  
    OP
       2021-03-11 13:42:22 +08:00
    @learningman 非常感谢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5159 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 05:53 PVG 13:53 LAX 21:53 JFK 00:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86