UniApp 实现双语功能

文章目录

在 UniApp 中实现双语功能(国际化)主要通过 vue-i18n 库实现,以下是详细步骤:

一. 安装依赖

bash 复制代码
npm install vue-i18n --save

管理员运行cmd,cd到项目路径,然后下载

二. 创建语言文件

在项目中创建语言资源目录:

复制代码
/src
  /locale
    en.json    # 英文资源
    zh-Hans.json # 中文资源
    zh-Hant.json # 繁体资源
    index.js # 主配置文件

语言文件示例
en.json:

javascript 复制代码
 {
  "login": {
		"title": "Query  Search",
		"ChangeLang":"Change Language",
		"prompt": "If there is no administrator account, please create an administrator first...",
		"username": "Account",
		"password": "Password",
		"captcha": "Captcha",
		"login": "Log In",
		"holder":"Please enter data"
	}
}

zh-Hans.json:

javascript 复制代码
{
  "login": {
		"title": "查询系统",
		"ChangeLang":"切换语言",
		"prompt": "如无账号,请联系管理员",
		"username": "账号",
		"password": "密码",
		"captcha": "验证码",
		"login": "登录",
		"holder":"请输入"
	}
}

zh-Hant.json:

javascript 复制代码
{
  "login": {
		"title": "查詢系統",
		"ChangeLang":"切換語言",
		"prompt": "如無賬號,請先聯繫管理員...",
		"username": "賬號",
		"password": "密碼",
		"captcha": "驗證碼",
		"login": "登錄",
		"holder":"請輸入"
	},
}

index.js:

javascript 复制代码
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
  en,
  'zh-Hans': zhHans,
  'zh-Hant': zhHant
}

三. 配置 i18n 实例

main.js:

1、VUE2配置I18N

javascript 复制代码
//I18N本地配置
import messages from './locale/index.js'
const lang = uni.getLocale()
// #ifndef VUE3
import VueI18n from 'vue-i18n'
import Vue from 'vue'
// 创建 VueI18n 实例
const i18n = new VueI18n({
	locale: lang, // 设置地区
	messages, // 设置地区信息
})
Vue.use(plugin)
App.mpType = 'app'
const app = new Vue({i18n,...App})
app.$mount()
// #endif

2、VUE3配置I18N

javascript 复制代码
// #ifdef VUE3
//I18N本地配置
import messages from './locale/index.js'
const lang = uni.getLocale()
import {
	createSSRApp
} from 'vue'
import {
	createI18n
} from 'vue-i18n'
// #endif
export function createApp() {
	const app = createSSRApp(App)
	//--VUE3配置I18N
	const i18n = createI18n({
		locale: lang,
		messages
	})
	app.use(i18n)
	//-i18n
	return {
		app
	}
}
// #endif

四. 页面中使用双语

html 复制代码
<template>
  <view>
    <text>{{ $t('welcome') }}</text>
    <button>{{ $t('button.confirm') }}</button>
  </view>
</template>

动态切换语言

javascript 复制代码
methods: {
  switchLanguage(lang) {
    // 实际切换语言逻辑
		uni.setLocale(lang)
		//刷新
		this.$i18n.locale = lang
  }
}

五、 实例

javascript 复制代码
<template>
	<view class="page">	
		<view class="title">
			<text class="titxt">{{$t("login.title")}}</text>
		</view>
		<view class="language">
			<view class="language-switcher">
				<!-- 语言切换按钮 -->
				<view class="language-btn" @click="toggleMenu">
					{{$t("login.ChangeLang")}}
					<uni-icons type="arrowdown" size="16"></uni-icons>
				</view>
				<!-- 下拉菜单 -->
				<view v-if="showMenu" class="dropdown-menu">
					<view v-for="lang in languages" :key="lang.value" class="menu-item"
						@click="switchLanguage(lang.value)">
						{{ lang.label }}
					</view>
				</view>
			</view>
		</view>
		<view class="content">
			<view class="row border">
				<text class="ctttit">{{$t("login.username")}}:</text> <input type="text" clearable v-model="username"
					:placeholder='$t("login.holder")'></input>
			</view>
			<view class="row border">
				<text class="ctttit">{{$t("login.password")}}:</text> <input type="password" displayable v-model="password"
					:placeholder='$t("login.holder")'></input>
			</view>
			<view class="btn-row">
				<button type="primary" class="primary" >{{$t("login.login")}}</button>
			</view>

		</view>
		
	</view>
</template>
<script>
	export default {
		//初始化数据
		data() {
			return {
				showMenu: false,
				currentLanguage: '中文',
				languages: [{
						label: 'English',
						value: 'en'
					}, {
						label: '中文简体',
						value: 'zh-Hans'
					},
					{
						label: '中文繁體',
						value: 'zh-Hant'
					}
				],
				username: '',
				password: '',
			}
		},
		//加载执行
		onLoad() {
		},
		methods: {
			toggleMenu() {
				this.showMenu = !this.showMenu
			},
			switchLanguage(lang) {
				this.currentLanguage = this.languages.find(l => l.value === lang).label
				this.showMenu = false
				// 实际切换语言逻辑
				uni.setLocale(lang)
				//刷新
				this.$i18n.locale = lang
			}
		}
	}
</script>
<style lang="scss" scoped>
	.page {
		display: flex;
		flex: 1;
		flex-direction: column;
		background: white;
		width: 100%;
		//                  overflow-x: hidden;
	}
	/*logo*/
	.header {
		width: 100%;
		margin: 0 auto;
		display: flex;
		justify-self: center;
		align-items: center;
		margin: 90rpx 0;

	}
	.logo-img {
		width: 440rpx;
		height: 90rpx;
		display: inline-block;
		border-radius: 10px;
		margin: 0 auto;
	}
	/*标题*/
	.title {
		position: relative;
		width: 100%;
		margin: 40rpx 0;
		height: 50rpx;
	}
	.title .titxt {
		width: 100%;
		display: flex;
		justify-self: center;
		align-items: center;
		text-align: center;
		display: inline-block;

		font-size: $font-tt;
	}
	/*内容*/
	.content {
		background-color: #ffffff;
		position: relative;
		width: 610rpx;
		margin: 0 auto;
	}
	.content::before {
		position: absolute;
		right: 0;
		top: 0;
		left: 0;
		height: 1px;
		content: '';
		-webkit-transform: scaleY(.5);
		transform: scaleY(.5);
		background-color: #FFFFFF;
	}
	.content::after {
		position: absolute;
		right: 0;
		bottom: 0;
		left: 0;
		height: 1px;
		content: '';
		-webkit-transform: scaleY(.5);
		transform: scaleY(.5);
		background-color: #c8c7cc;
	}
	.row {
		padding-top: 40rpx;

		margin: 0 auto;
		display: flex;
		flex-direction: row;
		position: relative;
		width: 100%;
		max-width: 460px;
		height: 50rpx;
		//line-height: 50rpx;

	}
	.row.border::after {
		position: absolute;
		right: 0;
		bottom: 0;
		left: 0px;
		height: 1px;
		content: '';
		-webkit-transform: scaleY(.5);
		transform: scaleY(.5);
		background-color: #c8c7cc;
	}
	.btn-row {
		margin-top: 0px;
		border-radius: 4px;
	}
	button.primary {
		margin-top: 40rpx;
		max-width: 460px;
		background: #3B88F5;
		width: 610rpx;
		color: #FFFFFF;
		font-family: PingFang SC;
		font-weight: 500;
		font-size: 30rpx;
		line-height: 66rpx;
		max-height: 66rpx;
		letter-spacing: 0px;
		text-align: center;
	}
	uni-input {
		font-size: $font-sm !important;
	}
	.ctttit {
		padding: 6rpx 10px;
		font-size: $font-sm;
		width: 30%;
	}
	.eicon {
		font-size: $font-icon !important;

	}
	.language {
		width: 100%;
		text-align: right;
	}
	.language-switcher {
		position: relative;
		display: inline-block;
		width: 180px;
		padding-right: 20px;
	}
	.language-btn {
		text-align: right;
		font-size: 14px;
		background-color: #fff;
		width: 180px;		
	}
	.dropdown-menu {
		position: absolute;
		top: 100%;
		right: 0;
		width: 120px;
		background-color: #fff;
		border: 1px solid #ddd;
		border-radius: 4px;
		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
		z-index: 100;
		margin-top: 4px;
	}
	.menu-item {
		padding: 12px 16px;
		text-align: center;
		border-bottom: 1px solid #eee;
	}
	.menu-item:last-child {
		border-bottom: none;
	}
	.menu-item:active {
		background-color: #f5f5f5;
	}
</style>

效果

相关推荐
会写代码的饭桶3 小时前
Jenkins 实现 Vue 项目自动化构建与远程服务器部署
vue.js·自动化·jenkins
被巨款砸中4 小时前
前端 20 个零依赖浏览器原生 API 实战清单
前端·javascript·vue.js·web
文韬_武略4 小时前
web vue之状态管理Pinia
前端·javascript·vue.js
董世昌414 小时前
js怎样改变元素的内容、属性、样式?
开发语言·javascript·ecmascript
mosen8684 小时前
【Vue】Vue Router4x关于router-view,transtion,keepalive嵌套写法报错
前端·javascript·vue.js
鸠摩智首席音效师5 小时前
如何清除 Yarn 缓存 ?
javascript
oh,huoyuyan6 小时前
如何在火语言中指定启动 Chrome 特定用户配置文件
前端·javascript·chrome
前端大聪明20026 小时前
single-spa原理解析
前端·javascript
一枚前端小能手6 小时前
📦 从npm到yarn到pnpm的演进之路 - 包管理器实现原理深度解析
前端·javascript·npm