Use vue-in vue3 i18n@9

Posted by sy-co on Sat, 05 Feb 2022 18:51:09 +0100

Use vue-in vue3 i18n@9

vue-i18n@9 Document Address Home | Vue I18n (intlify.dev)

vue-i18n is an internationalized plug-in for vue, which can easily integrate some localization functions into Vue.js project.

text

Download and Introduce

Temporarily unavailable

Local - Acts only on the current component

// HelloWorld Components
<<template>
  <div class="hello-world">
    <!-- t Is executed from useI18n Deconstruction of a function yields a function, hello Is a self-defined variable -->
    <p>{{ t("hello") }}</p>
    <p>{{ t("home.title") }}</p>
    <p>{{ hello }}</p>
  </div>
</template>

<script>
import { computed } from "vue";
import { useI18n } from "vue-i18n/index"; //Import and use

export default {
  setup() {
    const { t } = useI18n({
      // Pass in the messages object with the text to be scheduled. "zh-CN" - Chinese, "en-US" - English, the key s of the two objects must be identical.
      messages: {
        "zh-CN": {
          hello: "Hello,world",
          home: {
            title: "Welcome to Earth",
          },
        },
        "en-US": {
          hello: "hello, world",
          home: {
            title: "Welcome to the Earth",
          },
        },
      },
    });

    // t is a function that can be used in mustache (template syntax) and, of course, anywhere in the setup function
    const hello = computed(() => t("hello"));

    return {
      t,
      hello,
    };
  },
};
</script>

<style scoped>
</style>
<p>{{ t("hello") }}</p>
<p>{{ t("home.title") }}</p>
<p>{{ hello }}</p>
<p>Hello, world</p>
<p>Welcome to Earth</p>
<p>Hello, world</p>

Global - All components are available

  1. Pass in useScope to useI18n function: messages after "global" are global variables.
// App.vue component
// Of course, it can be any other component written here that conforms to the one-way data flow principle of vue, including the Switch Language button.
<template>
  <HelloWorld />
  <HelloChina></HelloChina>

  <!-- Provide user with switch language button -->
  <button @click="changeLang">in/English</button>
  <!-- If multilingual switching is required -->
  <select v-model="locale">
    <option value="zh-CN">Simplified Chinese</option>
    <option value="en-US">English</option>
  </select>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import HelloChina from "./components/HelloChina.vue";

import { useI18n } from "vue-i18n/index";

export default {
  name: "App",
  components: {
    HelloWorld,
    HelloChina,
  },
  setup(props) {
    const { locale } = useI18n({
      useScope: "global",
      messages: {
        "zh-CN": {
          hello2: "Hello,I am a global variable",
        },
        "en-US": {
          hello2: "hello, I'm global variable",
        },
      },
    });

    // Click Toggle
    const changeLang = () => {
      locale.value = "en-US"; // Executing useI18n when defining a global variable returns a locale, which changes the global language setting.
    };

    return {
      locale,
      changeLang
    };
  },
};
</script>

<style>
</style>

2. createI18n with globalInjection: true

// main.js
const i18n = createI18n({
  legacy: false,
  locale: 'zh-CN',
  fallbackLocale: 'en-US',
  globalInjection: true, // Add this sentence 
  // Setting it to true injects all properties and methods prefixed with $(only those carried by vue-i18n) into all Vue components.
  // That is, $i18n $t $rt $d $n $tm can be used in all components
})

app.use(i18n);
app.mount('#app');
  1. Using the global variable hello2
<template>
  <div class="hello-world">
    <p>{{ t("hello") }}</p>
    <p>{{ t("home.title") }}</p>
    <p>{{ hello }}</p>
    <!-- Notice that this is using $t(Now is the global method,No need to export) -->
    <p>{{ $t("hello2") }}</p>
  </div>
</template>
<p>Hello,I am a global variable</p>

Provide users with the option to switch languages

  • Executing useI18n when defining a global variable returns a locale, which changes the global language setting.

The code is App above. Code for Vue components

Common Syntax

Simple demonstration of common grammar, use details and advanced usage refer to the official documentation.

Message Format Syntax | Vue I18n (intlify.dev)

Text Localization

Named Interpolation

Similar to defining a parameter, parameters can be passed in when used.

"zh-CN": {
 name: "Hello,I am{uname}",
}
<p>{{ t("name", { uname: "tomato" }) }}</p>
<p>Hello,I am a tomato</p>
List Interpolation
"zh-CN": {
 skill: "I will{0}, {1}, {2}",
}
<p>{{ t("skill", ["html", "css", "javascript"]) }}</p>
<p>I will html, css, javascript</p>
Placeholder text interpolation

In i18n syntax, placeholder characters inserted between two variables must be wrapped in {'}, or they cannot be compiled.

  "en-US": {
    address: "{account}{'@'}{domain}"
  }
<p>email: {{ $t('address', { account: 'foo', domain: 'domain.com' }) }}</p>
<p>email: foo@domain.com</p>
Text Link

Use @: other variables can be referenced

"zh-CN": {
  firstName: "Taylor",
  lastName: "Swift",
  fullName: "@:firstName @:lastName !!!",
}
<p>{{ t("fullName") }}</p>
<p>Taylor Swift !!!</p>
Modifier-Built-in

vue-like event trigger modifier

"zh-CN": {
          tomato: "tomato",
          capital: "@.upper:tomato",
}
<p>{{ t("capital") }}</p>
<p>TOMATO</p>
Custom modifiers

Custom modifiers need to be defined when creating teI18n

const i18n = createI18n({
  locale: 'en-US',
  messages: {
    // set somethinig locale messages ...
  },
  // set custom modifiers at `modifiers` option
  modifiers: {
    snakeCase: (str) => str.split(' ').join('_')
  }
})

Pluralization

Plurals in the Most Common English

"en-US": {
  car: "car | cars",
  apple: "no apples | one apple | {count} apples",
},
<p>{{ t("car", 1) }}</p>
<p>{{ t("car", 2) }}</p>
<p>{{ t("apple", 0) }}</p>
<p>{{ t("apple", 1) }}</p>
<p>{{ t("apple", 2) }}</p>
<p>car</p>
<p>cars</p>

<p>no apples</p>
<p>one apple</p>
<p>2 apples</p>

Date Localization

  1. Incoming one more datetimeFormats object
  2. Export d Function
  3. Optional parameters in datetimeFormats ECMAScript® 2022 Internationalization API Specification (tc39.es)
setup() {
    const { t, d } = useI18n({
      messages: {
        'en-US': {
          current: 'Current Datetime'
        }
      },
     // Incoming one more datetimeFormats object
     datetimeFormats: {
        "zh-CN": {
          // Define the format to use
          // short shows only the year, month and day
          short: {
            year: "numeric",
            month: "short",
            day: "numeric",
          },
          // long shows the year, month, day, hour, second week
          long: {
            year: "numeric", // numeric: Display as a number (one digit shows one digit)
            month: "short", // short: short. For example, in English February - Feb. relative can be set to long
            day: "numeric", 
            weekday: "short",
            hour: "numeric",
            minute: "2-digit", //2-digit: Automatically precede by 0 when there is only one digit 
            second: "2-digit",
            hour12: true, // Whether to use 24-hour system. false | true
          },
        },
        "en-US": {
          short: {
            year: "numeric",
            month: "2-digit",
            day: "numeric",
          },
          long: {
            year: "numeric",
            month: "short",
            day: "2-digit",
            weekday: "long",
            hour: "numeric",
            minute: "2-digit",
            second: "2-digit",
            hour12: true,
          },
        },
      },
    })
    
    return {
      t,
      d,
    };
  }
<!-- to d Function passed in one Date Instances choose which way to show them -->
<p>{{ d(new Date(), "short") }}</p>
<p>{{ d(new Date(), "long") }}</p>
<p>2022 February 5, 2000</p>
<p>2022 Saturday, February 5, 2007, 7 p.m.:39:11</p>
<!-- and "en-US" -->
<p>02/5/2022</p>
<p>Saturday, Feb 05, 2022, 7:39:39 PM</p>

Digital Localization

Localization of different numbers, such as decimal to percentage, for currency symbols in different countries

  • This time, the n-function is exported, and the others are much the same as date localization.
setup() {
    const { t, n } = useI18n({
      messages: {
        'en-US': {
          current: 'Current Datetime'
        }
      },
     // Incoming one more numberFormats object
     numberFormats: {
        "zh-CN": {
          currency: {
            // This object is localization of currency
            style: "currency",
            // Renminbi (RMB)
            currency: "CNY",
            // Whether to use the three-digit subsection of numbers, i.e. 100,000,00
            useGrouping: true,
            // How to display the currency symbol.
            // code: CNY 100; symbol: 1000; name: 100 RMB;
            currencyDisplay: "symbol",
            // Digital notation: standard, scientific, engineering, etc.
            // standard:987,654,321.00; scientific:9.88E8; engineering:987.65E6; compact: 990 million;
            notation: "standard",
          },
          percent: {
            // Percentage localization. Display numbers as percentages.
            style: "percent",
            useGrouping: false,
            // How many decimal places to keep after conversion
            minimumFractionDigits: 2,
          },
          decimal: {
            // Decimal Localization
            style: "decimal",
            minimumSignificantDigits: 3,
            maximumSignificantDigits: 5,
          },
        },
        "en-US": {
          currency: {
            style: "currency",
            currency: "USD",
            notation: "standard",
          },
          decimal: {
            style: "decimal",
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
          },
          percent: {
            style: "percent",
            useGrouping: false,
          },
        },
      },
    })
    
    return {
      t,
      n
    };
  }
<p>{{ n(10000, "currency") }}</p>
<p>{{ n(10000, "currency", "en-US") }}</p>
<p>{{ n(10000, "currency", "zh-CN", { useGrouping: false }) }}</p>
<p>{{ n(987654321, "currency", { notation: "compact" }) }}</p>
<p>{{ n(0.99123, "percent") }}</p>
<p>{{ n(0.99123, "percent", { minimumFractionDigits: 3 }) }}</p>
<p>{{ n(12.11612345, "decimal") }}</p>
<p>{{ n(12145281111, "decimal", "en-US") }}</p>
<p>¥10,000.00</p>
<p>$10,000.00</p>
<p>¥10000.00</p>
<p>¥9.9 Billions</p>
<p>99.12%</p>
<p>99.123%</p>
<p>12.116</p>
<p>12,145,281,111.00</p>

Each component imports useI18n

Add a simple hook to reduce duplicate code (proofing). Import this hook from here.

import { useI18n } from "vue-i18n/index"; //Import Use

// Pass in an array
/*  
[
  ['Same key','value1','value2'],
  ['Same key','value1','value2'],
  ['Same key','value1','value2'],
]
 */
export default function useI18nHook(arr) {
  const messages = { 'zh-CN': {}, 'en-US': {} };

  arr.forEach(item => {
    messages['zh-CN'][item[0]] = item[1];
    messages['en-US'][item[0]] = item[2];
  });
  return useI18n({
    messages,
    // More fixed formatting configuration objects can also be included
    datetimeFormats: { 
      "zh-CN": {
        short: {
          year: "numeric",
          month: "short",
          day: "numeric",
        },
        long: {
          year: "numeric",
          month: "short",
          day: "numeric",
          weekday: "short",
          hour: "numeric",
          minute: "2-digit",
          second: "2-digit",
          hour12: true,
        },
      },
      "en-US": {
        short: {
          year: "numeric",
          month: "2-digit",
          day: "numeric",
        },
        long: {
          year: "numeric",
          month: "short",
          day: "2-digit",
          weekday: "long",
          hour: "numeric",
          minute: "2-digit",
          second: "2-digit",
          hour12: true,
        },
      },
    },
  });
}
// Use in Components
<script>
import useI18nHook from "@/hooks/useI18nHook.js";
export default {
  setup() {
    const { t } = useI18nHook([
      ["hello", "Hello, world", "hello, China"],
      ["uname", "William", "William"],
    ]);

    return {
      t,
    };
  },
};
</script>

Topics: Javascript Front-end Vue.js