添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reporting a bug?

In fact I guess this is not a bug, though I didn't find a workable way to solve this currently, after searching lots of docs, issues and pages. However I guess maybe the official reference of vue-i18n could describe the solution about this issue.

In some scenario, I want to create some reactive object containing translated i18n strings (via some reusable util functions) in setup() .

The official documentation of vue-i18n says If t(key) is used in a reactive context, it will re-evaluate once the locale changes. , however, I just cannot find a way to make the value reactive via steup() .

Module versions (please complete the following information):

  • vue : 3.x
  • vue-i18n : 9.x
  • Reproduction Link
    https://codesandbox.io/s/vue-i18n-reactive-in-setup-t9j3e

    <!DOCTYPE html>
    <html lang="en">
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Vue I18n v9 Starter Template</title>
      </head>
        <script src="https://unpkg.com/vue@next"></script>
        <script src="https://unpkg.com/vue-i18n@next"></script>
        <div id="app">
            <label>{{ $t('message.language') }}</label>
            <select v-model="curLang">
              <option value="en">en</option>
              <option value="ja">ja</option>
            </select>
          </form>
          <button v-on:click="showChild = !showChild">Toggle Child v-if</button>
          <p>{{ $t("message.directMsg") }}</p>
          <Child v-if="showChild"></Child>
        </div>
        <script>
          const { createApp, defineComponent, reactive, ref } = Vue;
          const { createI18n } = VueI18n;
          const i18n = createI18n({   // step 1
            legacy: false,
            globalInjection: true,
            locale: "en",
            messages: {
              en: {
                message: {
                  language: "Language",
                  directMsg: "Direct i18n.t()",
                  msgInObj: "i18n.t() in Object"
              ja: {
                message: {
                  language: "言語",
                  directMsg: "直接の i18n.t()",
                  msgInObj: "オブジェクト内の i18n.t()"
          const Child = defineComponent({
            template: `<p><b>Child Component, in setup():</b>
            <div>{{ directVal }}</div>   // step 5
            <div>{{ obj.indirectVal }}</div>
            </p>`,
            setup() {
              let directVal = i18n.global.t("message.directMsg");
              let obj = reactive({  // step 4
                indirectVal: i18n.global.t("message.msgInObj")
              return {
                directVal,
          const app = createApp({  // step 2
            components: {
              Child
            data() {
              return {
                showChild: true
            computed: {
              curLang: {
                get() {
                  return i18n.global.locale.value;
                set(nv) {
                  i18n.global.locale.value = nv;
          app.use(i18n);
          app.mount("#app");
          i18n.global.locale.value = "ja";   // step 3
        </script>
      </body>
    </html>
    

    To Reproduce
    Steps to reproduce the behavior:

  • Initialize an i18n instance (composition API, no legacy), with default locale: 'en'
  • Initialize Vue app instance and use() the i18n instance.
  • Change language with i18n.global.locale.value to ja
  • Create a reactive object tmpObj in <Child> component's setup() function, and add a property test into the object with the return value of i18n.global.t()
  • Access {{ tmpObj.test }} in the template of <Child>. Now it's translation is still in en.
  • Reload (please click the button Toggle Child v-if) the <Child>, Now it's translation will become ja. (because <Child>'s setup() is run again after i18n.global.locale.value changed.)
  • Expected behavior
    The <Child> should show ja string as soon as i18n.global.locale.value changed.

    Screenshots

    Additional context
    Cannot make the result of i18n.global.t() reactive Cannot make the result of i18n.global.t() reactive in object returned by setup() Jun 17, 2021

    @kuanyui try this, use computed, I just tested, it wrok:

    let directVal = computed(() => i18n.global.t("message.directMsg"));
    let obj = computed(() => {
        return { indirectVal: i18n.global.t("message.msgInObj") }
    

    https://codesandbox.io/s/vue-i18n-reactive-in-setup-forked-39duw