Vue前端使用I18实现中英文切换

这篇具有很好参考价值的文章主要介绍了Vue前端使用I18实现中英文切换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、配置vue-i18

1. 进入src/locales/index.js

import { createI18n } from 'vue-i18n'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
import enGB from 'ant-design-vue/es/locale/en_GB'
import zh_cn from './lang/zh-cn.js'
import en from './lang/en.js'

import tool from '@/utils/tool'
import sysConfig from '@/config/index'

export const messages = {
	'zh-cn': {
		lang: zhCN,
		...zh_cn
	},
	en: {
		lang: enGB,
		...en
	}
}

const i18n = createI18n({
	locale: tool.data.get('APP_LANG') || sysConfig.LANG,
	fallbackLocale: 'zh-cn',
	globalInjection: true,
	messages
})

export default i18n

2. 查看 src/utils/tool.js文件

import { notification } from 'ant-design-vue';

const tool = {}

// 以下使用中英翻译用到该方法!!!
// localStorage
tool.data = {
	set(table, settings) {
		const _set = JSON.stringify(settings)
		return localStorage.setItem(table, _set)
	},
	get(table) {
		let data = localStorage.getItem(table)
		try {
			data = JSON.parse(data)
		} catch (err) {
			return null
		}
		return data
	},
	remove(table) {
		return localStorage.removeItem(table)
	},

	clear() {
		return localStorage.clear()
	}
}

// sessionStorage
tool.session = {
	set(table, settings) {
		const _set = JSON.stringify(settings)
		return sessionStorage.setItem(table, _set)
	},
	get(table) {
		let data = sessionStorage.getItem(table)
		try {
			data = JSON.parse(data)
		} catch (err) {
			return null
		}
		return data
	},
	remove(table) {
		return sessionStorage.removeItem(table)
	},
	clear() {
		return sessionStorage.clear()
	}
}

// 千分符
tool.groupSeparator = (num) => {
	num = `${num}`
	if (!num.includes('.')) num += '.'

	return num
		.replace(/(\d)(?=(\d{3})+\.)/g, ($0, $1) => {
			return `${$1},`
		})
		.replace(/\.$/, '')
}

// 获取所有字典数组
tool.dictDataAll = () => {
	return tool.data.get('DICT_TYPE_TREE_DATA')
}

// 字典翻译方法,界面插槽使用方法 {{ $TOOL.dictType('sex', record.sex) }}
tool.dictTypeData = (dictValue, value) => {
	const dictTypeTree = tool.dictDataAll()
	if (!dictTypeTree) {
		return '需重新登录'
	}
	const tree = dictTypeTree.find((item) => item.dictValue === dictValue)
	if (!tree) {
		return '无此字典'
	}
	const children = tree.children
	const dict = children.find((item) => item.dictValue === value)
	return dict?.name || '无此字典'
}

// 获取某个code下字典的列表,多用于字典下拉框
tool.dictTypeList = (dictValue) => {
	const dictTypeTree = tool.dictDataAll()
	if (!dictTypeTree) {
		return []
	}
	const tree = dictTypeTree.find((item) => item.dictValue === dictValue)
	if (tree && tree.children) {
		return tree.children
	}
	return []
}

// 获取某个code下字典的列表,基于dictTypeList 改进,保留老的,逐步替换
tool.dictList = (dictValue) => {
	const dictTypeTree = tool.dictDataAll()
	if (!dictTypeTree) {
		return []
	}
	const tree = dictTypeTree.find((item) => item.dictValue === dictValue)
	if (tree) {
		return tree.children.map((item) => {
			return {
				value: item['dictValue'],
				label: item['name']
			}
		})
	}
	return []
}

// 生成UUID
tool.snowyUuid = () => {
	let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
		let r = (Math.random() * 16) | 0,
			v = c === 'x' ? r : (r & 0x3) | 0x8
		return v.toString(16)
	})
	// 首字符转换成字母
	return 'xn' + uuid.slice(2)
}

tool.sortBy = (property) => {
	return function (value1, value2) {
		let a = value1[property]
		let b = value2[property]

		return a < b ? 1 : a > b ? -1 : 0
	}
}

tool.sortBy = (property, asc) => {
	//默认升序,不能写在闭包里面,写在闭包里面是无效的……asc没反应就
	if (asc === undefined) {
		asc = -1
	} else {
		asc = asc ? -1 : 1
	}
	return function (value1, value2) {
		let a = value1[property]
		let b = value2[property]
		return a < b ? asc : a > b ? asc * -1 : 0
	}
}
/**
 * 打开消息面板
 * @param type 类型,success,info,warning,error
 * @param message 标题
 * @param description 备注
 * @param duration 弹出时间,默认3s
 */
export const showNotification = (type, message, description = '', duration = 3) => {
	notification[type]({
		message,
		description,
		duration
	})
}

// 文件处理工具end
export default tool

3. 查看 src/locales/lang/zh-cn.js、src/locales/lang/en.js

import 'dayjs/locale/zh-cn'

export default {
	common: {
		searchButton: '查询',
		resetButton: '重置',
		addButton: '增加',
		editButton: '编辑',
		removeButton: '删除',
		batchRemoveButton: '批量删除',
		detailButton: '详情',
		searchKey: '关键词',
		imports: '导入',
		more: '更多',
		export: '导出',
	},
	model: {
		user: '用户',
		org: '机构',
		pos: '职位',
		role: '角色',
		bizUser: '人员'
	},
	login: {
		signInTitle: '用户登录',
		forgetPassword: '忘记密码',
		signIn: '登录',
		signInOther: '其他登录方式',
		accountPlaceholder: '请输入账号',
		accountError: '请输入账号',
		PWPlaceholder: '请输入密码',
		PWError: '请输入密码',
		validLaceholder: '请输入验证码',
		validError: '请输入验证码',
		accountPassword: '账号密码',
		phoneSms: '手机号登录',
		phonePlaceholder: '请输入手机号',
		smsCodePlaceholder: '请输入短信验证码',
		getSmsCode: '获取验证码',
		machineValidation: '机器验证',
		sendingSmsMessage: '短信发送中',
		newPwdPlaceholder: '请输入新密码',
		backLogin: '返回登录',
		restPassword: '重置密码',
		emailPlaceholder: '请输入邮箱号',
		emailCodePlaceholder: '请输入邮件验证码',
		restPhoneType: '手机号找回',
		restEmailType: '邮箱找回',
        sysName: '管理'
	},
	user: {
		userStatus: '用户状态',
		resetPassword: '重置密码',
		role: '角色',
		batchExportButton: '批量导出',
		grantRole: '授权角色',
		grantResource: '授权资源',
		grantPermission: '授权权限',
		exportUserInfo: '导出信息',
		placeholderNameAndSearchKey: '请输入姓名或关键词',
		placeholderUserStatus: '请选择状态',
		popconfirmDeleteUser: '确定要删除吗?',
		popconfirmResatUserPwd: '确定要重置吗?'
	}
}
export default {
	common: {
		searchButton: 'search',
		resetButton: 'reset',
		addButton: 'add',
		editButton: 'edit',
		removeButton: 'delete',
		batchRemoveButton: 'batch Remove',
		detailButton: 'detail',
		searchKey: 'Search Key',
		imports: 'Import',
		more: 'More',
		export: 'Export',
	},
	model: {
		user: 'user',
		org: 'org',
		pos: 'pos',
		role: 'role',
		bizUser: 'bizUser'
	},
	login: {
		signInTitle: 'Sign in',
		forgetPassword: 'Forget password',
		signIn: 'Sign in',
		signInOther: 'Sign in with',
		accountPlaceholder: 'Please input a user account',
		accountError: 'Please input a user account',
		PWPlaceholder: 'Please input a password',
		PWError: 'Please input a password',
		validLaceholder: 'Please input a valid',
		validError: 'Please input a valid',
		accountPassword: 'Account Password',
		phoneSms: 'Phone SMS',
		phonePlaceholder: 'Please input a phone',
		smsCodePlaceholder: 'Please input a SMS code',
		getSmsCode: 'SMS code',
		machineValidation: 'Machine Validation',
		sendingSmsMessage: 'Sending SMS Message',
		newPwdPlaceholder: 'Please input a new password',
		backLogin: 'Back Login',
		restPassword: 'Rest Password',
		emailPlaceholder: 'Please input a email',
		emailCodePlaceholder: 'Please input a Email code',
		restPhoneType: 'For phone rest',
		restEmailType: 'For email rest',
		sysName: 'management'
	},
	user: {
		userStatus: 'User Status',
		resetPassword: 'Reset Password',
		role: 'Role',
		batchExportButton: 'Batch Export',
		grantRole: 'Grant Role',
		grantResource: 'Grant Resource',
		grantPermission: 'Grant Permission',
		exportUserInfo: 'Export UserInfo',
		placeholderNameAndSearchKey: 'Please enter your name or keyword',
		placeholderUserStatus: 'Please select status',
		popconfirmDeleteUser: 'Are you sure you want to delete it?',
		popconfirmResatUserPwd: 'Are you sure you want to reset?'
	}
}

二、配置页面

进入需要有翻译功能的页面进行配置,如 login.vue

1. HTML内容

<template>
	<div class="login_background">
		<div class="login_main">

            <!-- 配置小地球显示选择中英文翻译 -->
			<div class="login_config">
				<a-dropdown>
					<global-outlined />
					<template #overlay>
						<a-menu>
							<a-menu-item
								v-for="item in lang"
								:key="item.value"
								:command="item"
								:class="{ selected: config.lang === item.value }"
								@click="configLang(item.value)"
							>
								{{ item.name }}
							</a-menu-item>
						</a-menu>
					</template>
				</a-dropdown>
			</div>

            <!-- 配置登录表单 -->
			<div class="login-form">
				<a-card>
					<div class="login-header">
						<div class="logo">
                            <!-- 以下是通过sysBaseConfig动态获取图片和名称,此时名称是写死的并且需要中英翻译 -->
							<img :alt="sysBaseConfig.SNOWY_SYS_NAME" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
<!--							<label>{{ sysBaseConfig.SNOWY_SYS_NAME }}</label>-->

                            <!-- 因为配置文件的login中写了sysNme属性,使用{{ $t('login.sysName') }}进行显示 -->
							<label>{{ $t('login.sysName') }}</label>
						</div>
					</div>

					<a-tabs v-model:activeKey="activeKey">


                        <!-- 以下使用到配置文件的login中accountPassword、accountPlaceholder、PWPlaceholder、validLaceholder、signIn字段实现中英文翻译 -->
						<a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">
							<a-form ref="loginForm" :model="ruleForm" :rules="rules">
								<a-form-item name="account">
									<a-input
										v-model:value="ruleForm.account"
										:placeholder="$t('login.accountPlaceholder')"
										size="large"
										@keyup.enter="login"
									>
										<template #prefix>
											<UserOutlined class="login-icon-gray" />
										</template>
									</a-input>
								</a-form-item>

								<a-form-item name="password">
									<a-input-password
										v-model:value="ruleForm.password"
										:placeholder="$t('login.PWPlaceholder')"
										size="large"
										autocomplete="off"
										@keyup.enter="login"
									>
										<template #prefix>
											<LockOutlined class="login-icon-gray" />
										</template>
									</a-input-password>
								</a-form-item>

								<a-form-item name="validCode" v-if="captchaOpen === 'true'">
									<a-row :gutter="8">
										<a-col :span="17">
											<a-input
												v-model:value="ruleForm.validCode"
												:placeholder="$t('login.validLaceholder')"
												size="large"
												@keyup.enter="login"
											>
												<template #prefix>
													<verified-outlined class="login-icon-gray" />
												</template>
											</a-input>
										</a-col>
										<a-col :span="7">
											<img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
										</a-col>
									</a-row>
								</a-form-item>

								<a-form-item>
									<a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}?</a>
								</a-form-item>
								<a-form-item>
									<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
										>{{ $t('login.signIn') }}
									</a-button>
								</a-form-item>
							</a-form>
						</a-tab-pane>
<!--						<a-tab-pane key="userSms" :tab="$t('login.phoneSms')" force-render>-->
<!--							<phone-login-form />-->
<!--						</a-tab-pane>-->
					</a-tabs>
				</a-card>
			</div>
		</div>
	</div>
</template>

2. JS内容

<script>
	import loginApi from '@/api/auth/loginApi'
	import phoneLoginForm from './phoneLoginForm.vue'
	import threeLogin from './threeLogin.vue'
	import smCrypto from '@/utils/smCrypto'
	import { required } from '@/utils/formRules'
	import { afterLogin } from './util'
	import config from '@/config'
	import configApi from '@/api/dev/configApi'
	import tool from '@/utils/tool'
	import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
	import { mapActions, mapState } from 'pinia'

	export default {
		name: 'Login',
		components: {
		},
		data() {
			return {
				activeKey: 'userAccount',
				captchaOpen: config.SYS_BASE_CONFIG.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN,
				validCodeBase64: '',
				ruleForm: {
					account: '',
					password: '',
					validCode: '',
					validCodeReqNo: '',
					autologin: false
				},
				rules: {
					account: [required(this.$t('login.accountError'), 'blur')],
					password: [required(this.$t('login.PWError'), 'blur')]
				},
				loading: false,

                // 添加中英文切换功能(实现小地球图标的显示与切换)
				config: {
					lang: tool.data.get('APP_LANG') || this.$CONFIG.LANG,
					theme: tool.data.get('APP_THEME') || 'default'
				},

                // 小地球图标切换语言功能选择
				lang: [
					{
						name: '简体中文',
						value: 'zh-cn'
					},
					{
						name: 'English',
						value: 'en'
					}
				]

			}
		},
		computed: {
			...mapState(globalStore, ['sysBaseConfig']),
		},
		watch: {
			'config.theme': function (val) {
				document.body.setAttribute('data-theme', val)
			},

            // 添加中英文切换功能的配置实现(html中config.lang === item.value)
			'config.lang': function (val) {
				this.$i18n.locale = val
				tool.data.set('APP_LANG', val)
			}
		},
		created() {
			this.clearViewTags()
			this.clearKeepLive()
			this.clearIframeList()
		},
		mounted() {
			let formData = ref(config.SYS_BASE_CONFIG)
			configApi.configSysBaseList().then((data) => {
				if (data) {
					data.forEach((item) => {
						formData.value[item.configKey] = item.configValue
					})
					this.captchaOpen = formData.value.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN
					tool.data.set('SNOWY_SYS_BASE_CONFIG', formData.value)
					this.setSysBaseConfig(formData.value)
					this.refreshSwitch()
				}
			})
		},
		methods: {
			...mapActions(keepAliveStore, ['clearKeepLive']),
			...mapActions(viewTagsStore, ['clearViewTags']),
			...mapActions(iframeStore, ['clearIframeList']),
			...mapActions(globalStore, ['setSysBaseConfig']),
   
            // 点击语言后实现切换的方法,在HTML中@click="configLang(item.value)"
			configLang(key) {
				this.config.lang = key
			},

			// 通过开关加载内容
			refreshSwitch() {
				// 判断是否开启验证码
				if (this.captchaOpen === 'true') {
					// 加载验证码
					this.loginCaptcha()
					// 加入校验
					this.rules.validCode = [required(this.$t('login.validError'), 'blur')]
				}
			},
			// 获取验证码
			loginCaptcha() {
				loginApi.getPicCaptcha().then((data) => {
					this.validCodeBase64 = data.validCodeBase64
					this.ruleForm.validCodeReqNo = data.validCodeReqNo
				})
			},
			// 用户名密码登录
			async login() {
				this.$refs.loginForm.validate().then(async () => {
					this.loading = true
					const loginData = {
						account: this.ruleForm.account,
						// 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
						password: smCrypto.doSm2Encrypt(this.ruleForm.password),
						validCode: this.ruleForm.validCode,
						validCodeReqNo: this.ruleForm.validCodeReqNo
					}
					// 获取token
					try {
						const loginToken = await loginApi.login(loginData)
						await afterLogin(loginToken)
					} catch (err) {
						this.loading = false
						this.loginCaptcha()
					}
				})
			},
		}
	}
</script>

<!-- 引入该login页面的样式配置 -->
<style lang="less">
	@import 'login';
</style>

三、主要步骤

方法一

① 页面上添加小地球选择语言显示选项

<a-dropdown>
    <global-outlined />
    <template #overlay>
	    <a-menu>
			<a-menu-item
				v-for="item in lang"
			    :key="item.value"
				:command="item"
				:class="{ selected: config.lang === item.value }"
				@click="configLang(item.value)"
			>
				{{ item.name }}
			</a-menu-item>
		</a-menu>
    </template>
</a-dropdown>

② 实现添加的小地球功能

export default {
	data() {
		return {
			lang: [],

			config: {
                // lang 属性的值是通过 tool.data.get('APP_LANG') || this.$CONFIG.LANG 表达式获取的
                // 如果 tool.data.get('APP_LANG') 返回一个真值(非空、非undefined、非false等),则使用该值作为 lang 的值;否则,使用 this.$CONFIG.LANG 作为默认值。
				lang: tool.data.get('APP_LANG') || this.$CONFIG.LANG,

			}
		}
	},

    watch: {    // 当 config.lang 发生变化时,即语言设置发生变化时,触发绑定的回调函数

		'config.lang': function (val) {
            // 将新的语言设置应用到 $i18n 实例中,以改变应用程序的语言
			this.$i18n.locale = val
            // 将新的语言设置存储到 tool.data 中,以便在后续访问或导航到新页面时可以获取并应用语言设置
			tool.data.set('APP_LANG', val)
		}
	},
    methods: {
        // 更新 config.lang 的值
		configLang(key) {
			this.config.lang = key
		},
    }
}

③ 实现语言的切换选项显示

在上述 return {} 中的 lang: [] 填入数据

        lang: [
			{
				name: '简体中文',
				value: 'zh-cn'
			},
			{
				name: 'English',
				value: 'en'
			}
		]
方法二

① 页面上添加小地球选择语言显示选项

<a-dropdown v-if="!ismobile" class="panel-item">
	<global-outlined />
	<template #overlay>
		<a-menu :selected-keys="lang">
			<a-menu-item key="zh-cn" @click="handleIn18('zh-cn')">
				<span>简体中文</span>
			</a-menu-item>
			<a-menu-item key="en" @click="handleIn18('en')">
				<span>English</span>
			</a-menu-item>
		</a-menu>
	</template>
</a-dropdown>

② 在methods中添加点击选项后的切换功能

data() {
	return {
		lang: [],
	}
},
methods: {
	// 设置多语言语种
	handleIn18(key) {
        // 将 this.lang 数据初始化为空数组
		this.lang = []
        // 将传入的 key 值添加到 this.lang 数组中,用于保存语言数据
		this.lang.push(key)
        // 将语言设置应用到 $i18n 实例中,以改变应用程序的语言
		this.$i18n.locale = key
        // 将语言设置存储到 this.$TOOL.data 中,使用键名 'APP_LANG' 来标识。这样可以将语言设置持久化,以便在后续访问或导航到新页面时可以获取并应用语言设置
		this.$TOOL.data.set('APP_LANG', key)
	},
}

四、多页面使用相同语言

在以上方法中都将使得所有的页面用同一种语言,因为:

方法一中

'config.lang': function (val) {
    // 将新的语言设置应用到 $i18n 实例中,以改变应用程序的语言
    this.$i18n.locale = val
    // 将新的语言设置存储到 tool.data 中,以便在后续访问或导航到新页面时可以获取并应用语言设置 
    tool.data.set('APP_LANG', val)         
}

方法二中

    // 将语言设置应用到 $i18n 实例中,以改变应用程序的语言
    this.$i18n.locale = key
    // 将语言设置存储到 this.$TOOL.data 中,使用键名 'APP_LANG' 来标识。这样可以将语言设置持久化,以便在后续访问或导航到新页面时可以获取并应用语言设置
    this.$TOOL.data.set('APP_LANG', key)

lang 语言选择列表:

注意:如果想要获取的 lang 语言数据列表一致,而不需要自己重新定义的话,可以在此基础上添加如下代码:

created() {
	// 获取默认语言,根据之前存储的语言设置或默认的语言设置来确定数组的内容
    // this.$TOOL.data.get('APP_LANG') 从 this.$TOOL.data 中获取键名为 'APP_LANG' 的值,即之前存储的语言设置。如果之前没有存储语言设置,这个表达式的结果将为 undefined
    // this.$CONFIG.LANG 是一个变量,表示默认的语言设置
    // this.lang 的初始化通过 new Array() 创建一个新的数组。数组内容是通过三元运算符 || 进行判断
    // 如果 this.$TOOL.data.get('APP_LANG') 有值,则使用它作为数组的唯一元素;否则,使用 this.$CONFIG.LANG 作为数组的唯一元素。
	this.lang = new Array(this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG)
},

五、$t('') 无效

在一般情况下,只要在全局定义了 vue-i18(即配置了vue-i8),那么一般情况下是有用的,不管是哪种使用方式,如下两种示例:

<label>{{ $t('login.sysName') }}</label>
只是用label举例并不表示只有label有用
以下是 :tab、:placeholder 的举例
<a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">
<a-form ref="loginForm" :model="ruleForm" :rules="rules">
	<a-form-item name="account">
		<a-input
			v-model:value="ruleForm.account"
			:placeholder="$t('login.accountPlaceholder')"
			size="large"
			@keyup.enter="login"
		>
			<template #prefix>
				<UserOutlined class="login-icon-gray" />
			</template>
		</a-input>
	</a-form-item>
	<a-form-item name="password">
		<a-input-password
			v-model:value="ruleForm.password"
			:placeholder="$t('login.PWPlaceholder')"
			size="large"
			autocomplete="off"
			@keyup.enter="login"
		>
			<template #prefix>
				<LockOutlined class="login-icon-gray" />
			</template>
		</a-input-password>
	</a-form-item>
</a-form>

以上都属于正确演示,都是有效的,但是如果使用第二种方式,且直接用tab、:placeholder而没有加冒号 : 则失效,包括其他的比如 :title 等都要加 : 才有效。

原因:冒号“:”其实是v-bind的缩写,冒号后面绑定为变量,会动态变化的值;一般属性后面为常量。由于当前需要切换语言所以是动态的值绑定,需要冒号:或v-bind:才可变。

六、遍历List进行中英文切换

以下假设List集合中的字段为中文,英文的话更简单,就不举例了。

zh-cn.js

	menu: {
		'系统首页': '系统首页',
		'个人中心' : '个人中心',
		'其他': '其他'
	}
如果集合中的数据是中文就写中文的字段并使用单引号,如果是英文就不要单引号

en.js

	menu: {
		'系统首页': 'System Home',
		'个人中心' : 'Personal Center',
		'其他': 'Other'
	}
如果集合中的数据是中文就写中文的字段并使用单引号,如果是英文就不要单引号

HTML中

<!-- v-for="shortcut in shortcutList" 遍历集合shortcutList中的每一个数据并将其对象命名为shortcut -->
<a-col :span="6" :key="shortcut.id" v-for="shortcut in shortcutList">
	<shortcutCard
		:icon="shortcut.icon ? shortcut.icon : 'menu-outlined'"

		:label="$t('menu.'+shortcut.title)"

		@click="leaveFor(shortcut.path)"
	/>
</a-col>
其中 :label="$t('menu.'+shortcut.title)" 即引入menu中变量shortcut.title的值的数据

显示效果如下(List中没有的数据不会显示,比如像上面说些的'其他'字段):

vue-i18,vue3,vue.js,前端,javascript,anti-design-vuevue-i18,vue3,vue.js,前端,javascript,anti-design-vue

所以应用主要是:

{{ $t('menu.' + shortcut.title) }}
或者
:title="$t('menu.' + shortcut.title)"

七、在HTML、JS中使用$t()

1、HTML中使用$t()
{{ $t('menu.title'}}
或者
:title="$t('menu.title')"
2、JS中使用$t()

使用 this 引用 $t() 即 this.$t() ,注意JS中的 属性 :this.$t() 中属性是不需要冒号“:”的!!!

handleUser(key) {
    // 个人中心页面跳转
	if (key === 'uc') {
		router.push({ path: '/usercenter' })
	}

    // 点击清理缓存
	if (key === 'clearCache') {
		this.$confirm({
            // 提示
			title: this.$t('login.info'),
            // 提示内容
			content: this.$t('login.delCache'),
			icon: createVNode(ExclamationCircleOutlined),
			maskClosable: false,
            // 确认按钮
			okText: this.$t('button.sure'),
            // 取消按钮
			cancelText: this.$t('button.cancel'),
			onOk() {
				message.loading('正在清理中...', 1)
				tool.data.clear()
				setTimeout(() => {
					router.replace({ path: '/login' })
					location.reload()
				}, 100)
			},
			onCancel() {}
		})
	}

    // 退出登录
	if (key === 'outLogin') {
		this.$confirm({
            // 提示
			title: this.$t('login.info'),
            // 提示内容
			content: this.$t('login.logoutMessage'),
			icon: createVNode(ExclamationCircleOutlined),
			maskClosable: false,
            // 确认按钮
			okText: this.$t('button.sure'),
            // 取消按钮
			cancelText: this.$t('button.cancel'),
			onOk() {
				// 取得缓存中的token
				const token = tool.data.get('TOKEN')
				const param = {
					token: token
				}
				message.loading('退出中...', 1)
				loginApi
					.logout(param)
					.then(() => {
						// message.c
						// 清理掉个人的一些信息
						tool.data.remove('TOKEN')
						tool.data.remove('USER_INFO')
						tool.data.remove('MENU')
						tool.data.remove('PERMISSIONS')
						router.replace({ path: '/login' })
					})
					.catch(() => {
						tool.data.clear()
						router.replace({ path: '/login' })
						location.reload()
					})
			},
			onCancel() {}
		})
	}
},

以下是调用 handleUser 方法的HTML:

<a-menu>
<a-menu-item key="uc" @click="handleUser('uc')">
	<UserOutlined style="margin-right: 8px" />
	<span>{{ $t('index.userCenter') }}</span>
</a-menu-item>
<a-menu-item key="clearCache" @click="handleUser('clearCache')">
	<loading3-quarters-outlined style="margin-right: 8px" />
	<span>{{ $t('index.cleanCache') }}</span>
</a-menu-item>
<a-menu-divider />
<a-menu-item key="outLogin" @click="handleUser('outLogin')">
	<export-outlined style="margin-right: 8px" />
	<span>{{ $t('index.logout') }}</span>
</a-menu-item>
</a-menu>

效果如图:

vue-i18,vue3,vue.js,前端,javascript,anti-design-vuevue-i18,vue3,vue.js,前端,javascript,anti-design-vuevue-i18,vue3,vue.js,前端,javascript,anti-design-vue

vue-i18,vue3,vue.js,前端,javascript,anti-design-vuevue-i18,vue3,vue.js,前端,javascript,anti-design-vue

vue-i18,vue3,vue.js,前端,javascript,anti-design-vue

3、JS里的HTML部分中使用$t()
renderAlert() {
	// 绘制统计列数据
	// eslint-disable-next-line no-unused-vars
	const needTotalItems = this.needTotalList.map((item) => {
		return (
			<span className="mr-3">
						{item.title} 总计{' '}
				<a className="font-6">{!item.customRender ? item.total : item.customRender(item.total)}</a>
					</span>
		)
	})

	// 绘制 清空 按钮
	// eslint-disable-next-line no-unused-vars
	const clearItem =
		typeof this.alert === 'boolean' && this.alert
			? this.renderClear(this.clearSelected)
			: typeof this.alert.clear === 'function'
				? this.renderClear(this.alert.clear)
				: null

	// 绘制 alert 组件
	if (alert) {
		const message = (
			<div>
						<span className="mr-3">
							已选择 : <a className="font-6">{this.selectedRows.length}</a>
						</span>
				{needTotalItems}
				{clearItem}
			</div>
		)
		return <a-alert showIcon class="mb-4" message={message} />
	}
},

renderClear(callback) {
	if (this.selectedRowKeys.length <= 0) return null
	return (
		<a
			className="ml-6"
			onClick={() => {
				callback()
				this.clearSelected()
			}}>
			{' '}
			清空{' '}
		</a>
	)
},

vue-i18,vue3,vue.js,前端,javascript,anti-design-vue

切换多语言,修改代码:

renderClear(callback) {
	if (this.selectedRowKeys.length <= 0) return null
	return (
		<a
			className="ml-6"
			onClick={() => {
				callback()
				this.clearSelected()
			}}>
			{' '}
            <!-- 修改了此处 -->
			{ this.$t('button.clean') }{' '}
		</a>
	)
},
renderAlert() {
	// 绘制统计列数据
	// eslint-disable-next-line no-unused-vars
	const needTotalItems = this.needTotalList.map((item) => {
		return (
			<span className="mr-3">
						{item.title} 总计{' '}
				<a className="font-6">{!item.customRender ? item.total : item.customRender(item.total)}</a>
					</span>
		)
	})
	// 绘制 清空 按钮
	// eslint-disable-next-line no-unused-vars
	const clearItem =
		typeof this.alert === 'boolean' && this.alert
			? this.renderClear(this.clearSelected)
			: typeof this.alert.clear === 'function'
				? this.renderClear(this.alert.clear)
				: null
	// 绘制 alert 组件
	if (alert) {
		const message = (
			<div>
						<span className="mr-3">
                            <!-- 修改了此处 -->
							{ this.$t('table.selected') } : <a className="font-6">{this.selectedRows.length}</a>
						</span>
				{needTotalItems}
				{clearItem}
			</div>
		)
		return <a-alert showIcon class="mb-4" message={message} />
	}
},

vue-i18,vue3,vue.js,前端,javascript,anti-design-vue

4、对antd的<s-table>表头国际化i18n使用$t()

原始表格HTML:

<s-table
    ref="table"
    :columns="columns"
    :data="loadData"
    :alert="options.alert.show"
    bordered
    :row-key="(record) => record.id"
    :tool-config="toolConfig"
    :row-selection="options.rowSelection"
>

<template #operator class="table-operator">
  <a-space>
    <a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('sysSeriesAdd')">
      <template #icon><plus-outlined /></template>
      {{ $t('button.add') }}
    </a-button>
    <xn-batch-delete
        v-if="hasPerm('sysSeriesBatchDelete')"
        :selectedRowKeys="selectedRowKeys"
        @batchDelete="deleteBatchSysSeries"
    />
  </a-space>
</template>
<template #bodyCell="{ column, record }">
  <template v-if="column.dataIndex === 'picUrl'">
    <img :src="record.picUrl" alt="图片" style="width: 80px; height: 100px">
  </template>
  <template v-if="column.dataIndex === 'isOver'">
    {{ $TOOL.dictTypeData('COMMON_YES_OR_NO', record.isOver) }}
  </template>
  <template v-if="column.dataIndex === 'online'">
    {{ $TOOL.dictTypeData('COMMON_YES_OR_NO', record.online) }}
  </template>
  <template v-if="column.dataIndex === 'action'">
    <a-space>
      <a @click="batchBind(record)" v-if="hasPerm('sysSeriesBind')">{{ $t('button.bind') }}</a>
      <a-divider type="vertical" v-if="hasPerm(['sysSeriesBind'], 'and')" />
      <a @click="formRef.onOpen(record)" v-if="hasPerm('sysSeriesEdit')">{{ $t('common.editButton') }}</a>
      <a-divider type="vertical" v-if="hasPerm(['sysSeriesEdit', 'sysSeriesDelete'], 'and')" />
      <a-popconfirm :title="$t('user.popconfirmDeleteUser')" @confirm="deleteSysSeries(record)">
        <a-button type="link" danger size="small" v-if="hasPerm('sysSeriesDelete')">{{ $t('button.delete') }}</a-button>
      </a-popconfirm>
    </a-space>
  </template>
</template>

</s-table>

对表头以数组形式定义:

	const columns = [
		{
			title: '剧名',
			dataIndex: 'name'
		},
		{
			title: '总集数',
			dataIndex: 'totalVideo'
		},
		{
			title: '是否完结',
			dataIndex: 'isOver'
		},
		{
			title: '封面图',
			dataIndex: 'picUrl',
		},
		{
			title: '扩展信息',
			dataIndex: 'extJson',
			ellipsis: true
		},
		{
			title: '是否上架',
			dataIndex: 'online'
		},
		{
			title: '创建时间',
			dataIndex: 'createTime'
		},
		{
			title: '创建用户',
			dataIndex: 'createrName'
		}
	]

因为JS部分使用的是setup,并不是export default,在其中引用 $t 或者 this.$t 都报错,找不到 $t,所以国际化之后需要引入i18n,不是内部下载的vue-i18n:import { useI18n } from "vue-i18n";,而是自己编写的配置:import i18n from '@/locales';,

如图:vue-i18,vue3,vue.js,前端,javascript,anti-design-vue再:const { t } = i18n.global;,

代码如下:


<script setup name="xxx">

  // 从 @/locales 中导入一个名为 i18n 的对象(locales 文件用于处理国际化(i18n)相关的配置和逻辑)
  import i18n from '@/locales'

  // 从 i18n.global 对象中解构赋值一个名为 t 的变量
  // t 是一个函数或方法,用于国际化文本的翻译
  // i18n.global 是一个全局的 i18n 实例,包含了初始化和配置的信息。
  const { t } = i18n.global

  // 测试,刷新是识别到语言并进行打印
  console.log("打印出:", t('model.user'))
</script>

切换后刷新如下图:

vue-i18,vue3,vue.js,前端,javascript,anti-design-vuevue-i18,vue3,vue.js,前端,javascript,anti-design-vue

由于以上方法只能在页面刷新是获取到当前语言,所以需要在切换语言是进行页面刷新:

<a-dropdown>
  <global-outlined />
  <template #overlay>
    <a-menu :selected-keys="lang">
      <a-menu-item key="zh-cn" @click="handleIn18('zh-cn')">
        <span>简体中文</span>
      </a-menu-item>
      <a-menu-item key="en" @click="handleIn18('en')">
        <span>English</span>
      </a-menu-item>
    </a-menu>
  </template>
</a-dropdown>
    // 设置多语言语种
    handleIn18(key) {
      this.lang = []
      this.lang.push(key)
      this.$i18n.locale = key
      this.$TOOL.data.set('APP_LANG', key)
    
      // 页面刷新
      window.location.reload()
    },

之后的使用直接 t('xxx.xxx') 即可:

  const columns = [
    {
      title: t('table.seriesName'),
      dataIndex: 'name',
    },
    {
      title: t('table.allPlay'),
      dataIndex: 'totalVideo'
    },
    {
      title: t('table.isOver'),
      dataIndex: 'isOver'
    },
    {
      title: t('table.image'),
      dataIndex: 'picUrl',
    },
    {
      title: t('form.expand'),
      dataIndex: 'extJson',
      ellipsis: true
    },
    {
      title: t('table.isOn'),
      dataIndex: 'online'
    },
    {
      title: t('table.createTime'),
      dataIndex: 'createTime'
    },
    {
      title: t('table.createUser'),
      dataIndex: 'createrName'
    }
  ]

将判断部分也进行修改:

<template #bodyCell="{ column, record }">
  <template v-if="column.dataIndex === 'picUrl'">
    <img :src="record.picUrl" alt="图片" style="width: 80px; height: 100px">
  </template>

  <template v-if="column.dataIndex === 'isOver'">
    <div v-if="record.isOver === 'YES'">{{ $t('table.yes') }}</div>
    <div v-else>{{  $t('table.no') }}</div>
  </template>
  <template v-if="column.dataIndex === 'online'">
    <div v-if="record.online === 'YES'">{{ $t('table.yes') }}</div>
    <div v-else>{{  $t('table.no') }}</div>
  </template>

</template>
5、关于setup函数中的i18n的使用

即第4点antd中描述的那样:

// 引入自己配置的关于i18n的文件夹
import i18n from "@/locales";
const { t } = i18n.global

之后所有的需要 $t 或者 this.$t 的地方都使用 t 即可。文章来源地址https://www.toymoban.com/news/detail-857357.html

到了这里,关于Vue前端使用I18实现中英文切换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序英文版:实现一键切换中英双语版(已组件化)

    已经重新优化代码做成了组件,需要可自取:https://github.com/CrystalCAI11/wechat-language-compoment 所有操作都打包在组件里不需要在额外的地方添加代码,直接在你需要的页面里导入组件,再在对应页面的onLoad()里set文本就行了。 第一步,找个地方新建中英文两个字典,我是放在ut

    2024年04月17日
    浏览(60)
  • Qt 动态中英文切换

            需要界面实现动态国际化,一键点击切换中英文或其他语言。         已经完成了整个界面的翻译,拿到匹配的ts翻译文件,注意:要保证界面切换后,翻译的全覆盖,要保证任何需要反应的地方,都用到了tr(\\\"\\\")包含,不然Linguist会捕捉不到。.ts文件的生成参考下文

    2024年02月10日
    浏览(82)
  • pycharm界面中英文版本切换方法

    前言 新手报到,记录问题 pycharm还是喜欢英文版界面,那么如何实现中英文切换? 一、按下快捷键:CTRL+ALT+S,打开pycharm设置窗口 二、点击 Plugins ,选择 MarketPlace 文本框,输入 Chinese ,找到自己安装的中文插件 三、点击 Disable 或 Enable ,就可以禁用或启用插件实现中英文切

    2024年02月22日
    浏览(58)
  • Android开发-应用中英文(语言)切换(二)

            APP中针对不同国家不同地区的人群使用那么应用的语言自然也要能够随时进行切换,最近做的项目有中文和英文切换的需求,所以在了解了一下网上常用的方法后记录一下我使用的方法,只是简单的应用,后续如果有不同需求需要自己去改。♻          新建工程就

    2024年02月09日
    浏览(55)
  • vmware虚拟机Linux系统中英文输入法及切换方法

            许多同学在安装虚拟机联网之后,打开浏览器进行搜索时,发现无法正常进行中英文的切换,下面将简单介绍一下vmware虚拟机Linux系统( CentOS7)中英文输入法及切换方法。  1:打开虚拟机右上角的网络,点击设置的小图标 2:选择区域和语言( 地区和语言),然后在

    2024年02月12日
    浏览(43)
  • 花一分钟彻底搞懂Mac输入法/中英文/大小写切换

    最近有麦友说:没搞懂 Mac 怎么切换输入法、中英文和大小写,比如以前点按大写锁定键就可以切换到大写,现在要长按。有的时候点按大写锁定键或 shift 键都可以切换中英文,有的时候又不行。切换的时候基本就是碰运气瞎按。 之所以会有这种感觉,可能是因为以下几点:

    2024年02月07日
    浏览(62)
  • QT+C++桌面程序窗体框架模板-中英文切换-文件打开历史记录-工具选项设置

    程序示例精选 QT+C++桌面程序窗体框架模板-中英文切换-文件打开历史记录-工具选项设置 如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助! 这篇博客针对《QT+C++桌面程序窗体框架模板-中英文切换-文件打开历史记录-工具选项设置》编写代码,

    2024年01月24日
    浏览(56)
  • 前端 字体设置,中英文对照表 常用字体种类

    华文细黑:STHeiti Light [STXihei] 华文黑体:STHeiti 华文楷体:STKaiti 华文宋体:STSong 华文仿宋:STFangsong 儷黑 Pro:LiHei Pro Medium 儷宋 Pro:LiSong Pro Light 標楷體:BiauKai 蘋果儷中黑:Apple LiGothic Medium 蘋果儷細宋:Apple LiSung Light 新細明體:PMingLiU 細明體:MingLiU 標楷體:DFKai-SB 黑体:

    2024年02月07日
    浏览(92)
  • PYTHON实现AES加密,中英文通用!!!

    AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。在日常的开发中,无论是实现前后端的接口数据加密,还是数据传输安全性,都使用了AES加密,本文章将从python的角度去实现AES的加密和解密 AES的加密方式有很多种,例如ECB、CBC、CTR、OFB、CFB,最常用的是

    2024年02月12日
    浏览(54)
  • Android安卓实战项目(12)—关于身体分析,BMI计算,喝水提醒,食物卡路里计算APP【支持中英文切换】生活助手类APP(源码在文末)

    B站演示 【Android安卓实战项目(12)—生活助手类APP—关于身体分析,BMI计算,喝水提醒,食物卡路里计算APP【支持中英文切换】】 https://www.bilibili.com/video/BV1Wu4y1C76j/?share_source=copy_webvd_source=b2e9b9ed746acda34f499009647748ed 这段代码是一个Android应用程序的主要活动(Activity),它是一

    2024年02月10日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包