如果是 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 = getDicts

App.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. 优先使用 localStorage
  let 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,这里必须设置为false
  locale: 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-select
          v-model="locale"
          @change="changeLanguage"
          style="width: 140px"
        >
          <el-option
            v-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. 优先使用 localStorage
  let 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,这里必须设置为false
  locale: 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>

在uniapp中需要把底部导航的展示内容也根据语言包配置切换

//在每个语言配置的文件中先将键名和键值配置好
//如
export default{
	tabBar:{
		mine:'我的',
		home:'首页'
	},
	title:{
		ceshi:'测试'
	}
}
//先将text的值替换为对应的键名
"tabBar": {
		"color": "#000000",
		"selectedColor": "#000000",
		"borderStyle": "white",
		"backgroundColor": "#ffffff",
		"list": [{
				"pagePath": "pages/index",
				"iconPath": "static/images/tabbar/home.png",
				"selectedIconPath": "static/images/tabbar/home_.png",
				"text": "home"
			},
			// {
			// 	"pagePath": "pages/work/index",
			// 	"iconPath": "static/images/tabbar/work.png",
			// 	"selectedIconPath": "static/images/tabbar/work_.png",
			// 	"text": "工作台"
			// }, 
			{
				"pagePath": "pages/my/index",
				"iconPath": "static/images/tabbar/mine.png",
				"selectedIconPath": "static/images/tabbar/mine_.png",
				"text": "mine"
			}
		]
	},
	//然后再App.vue文件中配置默认展示的语言包
	onLaunch: function() {
		this.setTabBarText();
	},
	methods:{
		setTabBarText() {
			const tabBarList = [{
					index: 0,
					text: this.$t('tabBar.home')
				},
				{
					index: 1,
					text: this.$t('tabBar.mine')
				}
			];
			tabBarList.forEach(item => {
				wx.setTabBarItem({
					index: item.index,
					text: item.text
				});
			});
		},
	}
	//最后在切换语言包的组件里面添加事件  switch.vue
	//如点击事件
	changeLanguage(language) {
		this.locale = language;
		localStorage.setItem("language", language);
		this.$i18n.locale = language; // 确保 Vue-i18n 的语言切换
		this.$nextTick(() => {
			this.setTabBarText();
		});
	},
	//这样在切换语言的时候底部导航也会一起改变
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐