vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

<i18n-t> message scope resolution should start at current component

Open semiaddict opened this issue 4 years ago • 1 comments
trafficstars

Reporting a bug?

If a child component declares i18n messages, i18n-t will not find the parent messages. It seems to stop searching in the hierarchy once it finds a component with i18n messages.

Example, in the C1 component below, the translation keys hello and world should use the component's i18n messages, even if C2 and C3 declare their own i18n messages.

C1.vue:

<template>
  <div>
    C1:
    <div>{{ $t("hello", { world: $t("world") }) }}</div>
    <i18n-t keypath="hello" tag="div">
      <template #world>
        <strong>{{ $t("world") }}</strong>
      </template>
    </i18n-t>

    <br />

    <C2>
      <div>{{ $t("hello", { world: $t("world") }) }}</div>
      <i18n-t keypath="hello" tag="div">
        <template #world>
          <strong>{{ $t("world") }}</strong>
        </template>
      </i18n-t>

      <C3>
      <div>{{ $t("hello", { world: $t("world") }) }}</div>
      <i18n-t keypath="hello" tag="div">
        <template #world>
          <strong>{{ $t("world") }}</strong>
        </template>
      </i18n-t>
      </C3>
    </C2>
  </div>
</template>

<script>
import C2 from "./C2";
import C3 from "./C3";
export default {
  components: {
    C2,
    C3,
  },
  i18n: {
    messages: {
      en: {
        hello: "Hello {world}",
        world: "world!",
      },
    },
  },
};
</script>

C2.vue:

<template>
  <div>C2 slot: <slot></slot></div>
</template>

<script>
export default {
  i18n: {
    messages: {
      en: {
        goodbuy: "Goodbuy!",
      },
    },
  },
};
</script>

C3.vue:

<template>
  <div>C3 slot: <slot></slot></div>
</template>

<script>
export default {
  i18n: {
    messages: {
      en: {
        hello: "Hello {world} - C3",
        world: "world! - C3",
      },
    },
  },
};
</script>

However, in the <C2> block on the C1 component, the keys hello and world are not resolved, as they are not found in C2, and in the <C3> block on the C1 component, the keys resolve to the values found in the C3 component.

Originally posted by @semiaddict in https://github.com/intlify/vue-i18n-next/issues/708#issuecomment-937623157

Expected behavior

In both cases, the hello and world should resolve to C1's values.

Reproduction

A reproduction example can be found in branch issue-708 of https://github.com/semiaddict/vue-i18n-transition-bug/tree/issue-708

System Info

System:
  OS: Linux 4.19 Debian GNU/Linux 9 (stretch) 9 (stretch)
  CPU: (8) x64 Intel(R) Core(TM) i7-4712HQ CPU @ 2.30GHz
  Memory: 2.80 GB / 7.77 GB
  Container: Yes
  Shell: 4.4.12 - /bin/bash
Binaries:
  Node: 14.16.0 - ~/.nvm/versions/node/v14.16.0/bin/node
  Yarn: 1.22.15 - ~/.nvm/versions/node/v14.16.0/bin/yarn
  npm: 7.24.1 - ~/.nvm/versions/node/v14.16.0/bin/npm
npmPackages:
  vue: ^3.2.6 => 3.2.19 
  vue-i18n: ^9.1.8 => 9.1.9

Screenshot

No response

Additional context

No response

Validations

semiaddict avatar Oct 08 '21 09:10 semiaddict

Thank you for your reporting!

we need to revise the internal structure of vue-i18n a bit, so to solve this issue. And we need to investigate if Vue provides a way to know where the i18n-t component was resolved in the slot.

This issue resolving is going to take some more time.

kazupon avatar Oct 11 '21 03:10 kazupon