使用vue-i18n实现语言切换
如果是 Vue 3,确保 vue-i18n 的版本是 9.x 以上 npm install vue-i18n@9
。
如果是 Vue 2,确保 vue-i18n 的版本是 8.x 以下 npm install vue-i18n@8
。
1.vue2写法
main.js配置
import Vue from 'vue'
import App from './App'
import store from './store' // store
import plugins from './plugins' // plugins
import './permission' // permission
import {getDicts
} from "@/api/system/dict/data"
import uView from "uview-ui";
import i18n from "@/language/index.js"; // 引入 i18n
Vue.use(uView);
Vue.use(plugins)Vue.config.productionTip = false
Vue.prototype.$store = store
Vue.prototype.getDicts = getDictsApp.mpType = 'app'const app = new Vue({...App,i18n
})app.$mount()
新建一个文件夹存放各版本语言 index.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import enUS from "./locales/en_US";
import kmKH from "./locales/km_KH";
import zhCN from "./locales/zh_CN";// 支持的语言
const SUPPORTED_LANGS = ["zh-CN", "en-US", "km-KH"];// 获取并规范化语言
const getLanguage = () => {// 1. 优先使用 localStoragelet lang = localStorage.getItem("language");// 2. 其次根据浏览器语言自动判断if (!lang) {const nav = navigator.language.toLowerCase();if (nav.startsWith("zh")) {lang = "zh-CN";} else if (nav.startsWith("en")) {lang = "en-US";} else if (nav.startsWith("km")) {lang = "km-KH";} else {lang = "zh-CN";}}// 3. 确保语言被支持if (!SUPPORTED_LANGS.includes(lang)) {lang = "zh-CN";}// 4. 确保 localStorage 是标准格式localStorage.setItem("language", lang);return lang;
};const language = getLanguage();
Vue.use(VueI18n);
const i18n = new VueI18n({legacy: false, // 使用Composition API,这里必须设置为falselocale: language, // 默认显示语言fallbackLocale: "zh-US", // 当语言找不到时,用中文兜底globalInjection: true, // 全局注册$t方法messages: {// 配置语言对应的文件"zh-CN": zhCN,"en-US": enUS,"km-KH": kmKH,},
});export default i18n;
层级如下
页面中使用
<template><view class="content"><view class="title"><p class="header">{{ $t("menu.title") }}</p><view class="home"><div class="homeimg"><p>{{ $t("login.title") }}</p></div></view></view><view class="container"><view v-for="item in data" :key="item.name"><uni-section :title="$t(menuTitle[item.name])" type="line"></uni-section><view class="grid-body"><uni-grid :column="4" :showBorder="false" @change="changeGrid"><uni-grid-item v-for="i in item.children" :key="i.name"><view class="grid-item-box"><u-icon :name="i.img" :size="80"></u-icon><text class="text">{{ $t(menuTitle[i.name]) }}</text></view></uni-grid-item></uni-grid></view></view></view></view>
</template><script>
export default {data() {return {data: [{name: 'scgl',children: [{name: 'scll',url: '',img: require('../static/icon/name.png')},]},]};},computed: {menuTitle() {return this.$t('menuTitle');}},methods: {changeGrid(e) {this.$modal.showToast('模块建设中~');}}
};
</script>
封装一个组件用于切换语言
<template><div class="language-switch-box"><div class="change-box"><template v-if="optionType === 'text'"><span@click="changeLanguage('zh-CN')":class="{ active: locale === 'zh-CN' }">中文</span>|<span@click="changeLanguage('en-US')":class="{ active: locale === 'en-US' }">English</span>|<span@click="changeLanguage('km-KH')":class="{ active: locale === 'km-KH' }">ខ្មែរ</span></template><template v-else><el-selectv-model="locale"@change="changeLanguage"style="width: 140px"><el-optionv-for="(value, key) in languageDict":key="key":label="value":value="key"/></el-select></template></div></div>
</template><script>
import { useI18n } from "vue-i18n";export default {props: {optionType: {type: String,default: "text",},},data() {return {locale: localStorage.getItem("language") || "zh-CN",languageDict: {"zh-CN": "中文","en-US": "English","km-KH": "ខ្មែរ",},};},methods: {changeLanguage(language) {this.locale = language;localStorage.setItem("language", language);console.log("切换语言:", language);console.log("当前 locale:", this.locale);},},watch: {locale(newLocale) {this.$i18n.locale = newLocale;},},
};
</script>
2.vue3写法
main.js配置
import i18n from "@/language"; // 引入 i18n
app.use(i18n);
新建一个文件夹存放各版本语言 index.js
import { createI18n } from "vue-i18n";
import enUS from "./locales/en_US";
import kmKH from "./locales/km_KH";
import zhCN from "./locales/zh_CN";// 支持的语言
const SUPPORTED_LANGS = ["zh-CN", "en-US", "km-KH"];// 获取并规范化语言
const getLanguage = () => {// 1. 优先使用 localStoragelet lang = localStorage.getItem("language");// 2. 其次根据浏览器语言自动判断if (!lang) {const nav = navigator.language.toLowerCase();if (nav.startsWith("zh")) {lang = "zh-CN";} else if (nav.startsWith("en")) {lang = "en-US";} else if (nav.startsWith("km")) {lang = "km-KH";} else {lang = "zh-CN";}}// 3. 确保语言被支持if (!SUPPORTED_LANGS.includes(lang)) {lang = "zh-CN";}// 4. 确保 localStorage 是标准格式localStorage.setItem("language", lang);return lang;
};const language = getLanguage();const i18n = createI18n({legacy: false, // 使用Composition API,这里必须设置为falselocale: language, // 默认显示语言fallbackLocale: "zh-CN", // 当语言找不到时,用中文兜底globalInjection: true, // 全局注册$t方法messages: {// 配置语言对应的文件"zh-CN": zhCN,"en-US": enUS,"km-KH": kmKH,},
});export default i18n;
语言包层级同上、用法同上、只是导入方法不同
问题记录
当需要动态使用语言包中的键
可以使用以下两种写法
<uni-section :title="$t(`menuTitle.${item.name}`)" type="line"></uni-section>
<text class="text">{{ $t(`menuTitle.${i.name}`) }}</text>
computed: {menuTitle() {return (key) => this.$t(`menuTitle.${key}`);}},<uni-section :title="menuTitle(item.name)" type="line"></uni-section>
<text class="text">{{ menuTitle(i.name) }}</text>