在vue3使用vue-i18n@9
vue-i18n@9文档地址Home | Vue I18n (intlify.dev)
vue-i18n是vue的国际化插件, 它可以轻松将一些本地化功能集成到Vue.js项目中.
Get Started
下载并引入
暂时无法使用 <script setup> 写法
局部 - 只作用于当前组件
<<template>
<div class="hello-world">
<!-- t是从执行useI18n函数的解构得到函数, hello是自己定义的变量 -->
<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";
export default {
setup() {
const { t } = useI18n({
messages: {
"zh-CN": {
hello: "你好,世界",
home: {
title: "欢迎来到地球",
},
},
"en-US": {
hello: "hello, world",
home: {
title: "Welcome to the Earth",
},
},
},
});
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>你好, 世界</p>
<p>欢迎来到地球</p>
<p>你好, 世界</p>
全局 - 所有组件都能使用
- 给
useI18n 函数传入useScope: "global" 后再传入的messages 即是全局变量.
<template>
<HelloWorld />
<HelloChina></HelloChina>
<!-- 给用户提供切换语言按钮 -->
<button @click="changeLang">中/English</button>
<!-- 如果需要多语言切换 -->
<select v-model="locale">
<option value="zh-CN">简体中文</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: "你好,我是全局变量",
},
"en-US": {
hello2: "hello, I'm global variable",
},
},
});
const changeLang = () => {
locale.value = "en-US";
};
return {
locale,
changeLang
};
},
};
</script>
<style>
</style>
? 2. createI18n 时加上globalInjection: true
const i18n = createI18n({
legacy: false,
locale: 'zh-CN',
fallbackLocale: 'en-US',
globalInjection: true,
})
app.use(i18n);
app.mount('#app');
- 使用全局变量
hello2
<template>
<div class="hello-world">
<p>{{ t("hello") }}</p>
<p>{{ t("home.title") }}</p>
<p>{{ hello }}</p>
<p>{{ $t("hello2") }}</p>
</div>
</template>
<p>你好,我是全局变量</p>
给用户提供切换语言选项
- 在定义全局变量时执行useI18n时会返回一个locale, 改变其即改变全局语言设置.
代码即上面App.vue组件的代码
常见语法
简单演示常见语法, 使用细节及高级用法请参照官方文档.
Message Format Syntax | Vue I18n (intlify.dev)
文本本地化
具名插值
类似定义一个形参, 使用时可以传入参数.
"zh-CN": {
name: "你好,我是{uname}",
}
<p>{{ t("name", { uname: "番茄" }) }}</p>
<p>你好,我是番茄</p>
列表插值
"zh-CN": {
skill: "我会{0}, {1}, {2}",
}
<p>{{ t("skill", ["html", "css", "javascript"]) }}</p>
<p>我会html, css, javascript</p>
占位文字插值
在i18n的语法中, 在两个变量之间插入占位字符必须使用 { ’ ’ }包裹, 否则无法编译.
"en-US": {
address: "{account}{'@'}{domain}"
}
<p>email: {{ $t('address', { account: 'foo', domain: 'domain.com' }) }}</p>
<p>email: foo@domain.com</p>
文本链接
使用@: 可以引用其他变量
"zh-CN": {
firstName: "Taylor",
lastName: "Swift",
fullName: "@:firstName @:lastName !!!",
}
<p>{{ t("fullName") }}</p>
<p>Taylor Swift !!!</p>
修饰符 - 内置
类似vue的事件触发修饰符
"zh-CN": {
tomato: "tomato",
capital: "@.upper:tomato",
}
<p>{{ t("capital") }}</p>
<p>TOMATO</p>
自定义修饰符
在createI18n时就需将自定义修饰符定义好
const i18n = createI18n({
locale: 'en-US',
messages: {
},
modifiers: {
snakeCase: (str) => str.split(' ').join('_')
}
})
复数本地化
最常见的英语中的复数
"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>
日期本地化
- 多传入一个datetimeFormats对象
- 导出
d 函数 - datetimeFormats中的可选参数 ECMAScript? 2022 Internationalization API Specification (tc39.es)
setup() {
const { t, d } = useI18n({
messages: {
'en-US': {
current: 'Current Datetime'
}
},
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,
},
},
},
})
return {
t,
d,
};
}
<!-- 给d函数传入一个Date实例再选择使用哪种方式展示 -->
<p>{{ d(new Date(), "short") }}</p>
<p>{{ d(new Date(), "long") }}</p>
<p>2022年2月5日</p>
<p>2022年2月5日周六 下午7:39:11</p>
<p>02/5/2022</p>
<p>Saturday, Feb 05, 2022, 7:39:39 PM</p>
数字本地化
不同国家货币符号的不同、小数转百分比等数字的本地化
setup() {
const { t, n } = useI18n({
messages: {
'en-US': {
current: 'Current Datetime'
}
},
numberFormats: {
"zh-CN": {
currency: {
style: "currency",
currency: "CNY",
useGrouping: true,
currencyDisplay: "symbol",
notation: "standard",
},
percent: {
style: "percent",
useGrouping: false,
minimumFractionDigits: 2,
},
decimal: {
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亿</p>
<p>99.12%</p>
<p>99.123%</p>
<p>12.116</p>
<p>12,145,281,111.00</p>
每个组件都要导入useI18n
补充一个简易hook, 来减少编写重复代码 (打个样). 从此导入这个hook即可.
import { useI18n } from "vue-i18n/index";
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,
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,
},
},
},
});
}
<script>
import useI18nHook from "@/hooks/useI18nHook.js";
export default {
setup() {
const { t } = useI18nHook([
["hello", "你好, 世界", "hello, China"],
["uname", "威廉", "William"],
]);
return {
t,
};
},
};
</script>
|