您现在的位置是:首页 > 技术教程 正文

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

admin 阅读: 2024-03-30
后台-插件-广告管理-内容页头部广告(手机)

一、配置vue-i18

1. 进入src/locales/index.js

  1. import { createI18n } from 'vue-i18n'
  2. import zhCN from 'ant-design-vue/es/locale/zh_CN'
  3. import enGB from 'ant-design-vue/es/locale/en_GB'
  4. import zh_cn from './lang/zh-cn.js'
  5. import en from './lang/en.js'
  6. import tool from '@/utils/tool'
  7. import sysConfig from '@/config/index'
  8. export const messages = {
  9. 'zh-cn': {
  10. lang: zhCN,
  11. ...zh_cn
  12. },
  13. en: {
  14. lang: enGB,
  15. ...en
  16. }
  17. }
  18. const i18n = createI18n({
  19. locale: tool.data.get('APP_LANG') || sysConfig.LANG,
  20. fallbackLocale: 'zh-cn',
  21. globalInjection: true,
  22. messages
  23. })
  24. export default i18n

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

  1. import { notification } from 'ant-design-vue';
  2. const tool = {}
  3. // 以下使用中英翻译用到该方法!!!
  4. // localStorage
  5. tool.data = {
  6. set(table, settings) {
  7. const _set = JSON.stringify(settings)
  8. return localStorage.setItem(table, _set)
  9. },
  10. get(table) {
  11. let data = localStorage.getItem(table)
  12. try {
  13. data = JSON.parse(data)
  14. } catch (err) {
  15. return null
  16. }
  17. return data
  18. },
  19. remove(table) {
  20. return localStorage.removeItem(table)
  21. },
  22. clear() {
  23. return localStorage.clear()
  24. }
  25. }
  26. // sessionStorage
  27. tool.session = {
  28. set(table, settings) {
  29. const _set = JSON.stringify(settings)
  30. return sessionStorage.setItem(table, _set)
  31. },
  32. get(table) {
  33. let data = sessionStorage.getItem(table)
  34. try {
  35. data = JSON.parse(data)
  36. } catch (err) {
  37. return null
  38. }
  39. return data
  40. },
  41. remove(table) {
  42. return sessionStorage.removeItem(table)
  43. },
  44. clear() {
  45. return sessionStorage.clear()
  46. }
  47. }
  48. // 千分符
  49. tool.groupSeparator = (num) => {
  50. num = `${num}`
  51. if (!num.includes('.')) num += '.'
  52. return num
  53. .replace(/(\d)(?=(\d{3})+\.)/g, ($0, $1) => {
  54. return `${$1},`
  55. })
  56. .replace(/\.$/, '')
  57. }
  58. // 获取所有字典数组
  59. tool.dictDataAll = () => {
  60. return tool.data.get('DICT_TYPE_TREE_DATA')
  61. }
  62. // 字典翻译方法,界面插槽使用方法 {{ $TOOL.dictType('sex', record.sex) }}
  63. tool.dictTypeData = (dictValue, value) => {
  64. const dictTypeTree = tool.dictDataAll()
  65. if (!dictTypeTree) {
  66. return '需重新登录'
  67. }
  68. const tree = dictTypeTree.find((item) => item.dictValue === dictValue)
  69. if (!tree) {
  70. return '无此字典'
  71. }
  72. const children = tree.children
  73. const dict = children.find((item) => item.dictValue === value)
  74. return dict?.name || '无此字典'
  75. }
  76. // 获取某个code下字典的列表,多用于字典下拉框
  77. tool.dictTypeList = (dictValue) => {
  78. const dictTypeTree = tool.dictDataAll()
  79. if (!dictTypeTree) {
  80. return []
  81. }
  82. const tree = dictTypeTree.find((item) => item.dictValue === dictValue)
  83. if (tree && tree.children) {
  84. return tree.children
  85. }
  86. return []
  87. }
  88. // 获取某个code下字典的列表,基于dictTypeList 改进,保留老的,逐步替换
  89. tool.dictList = (dictValue) => {
  90. const dictTypeTree = tool.dictDataAll()
  91. if (!dictTypeTree) {
  92. return []
  93. }
  94. const tree = dictTypeTree.find((item) => item.dictValue === dictValue)
  95. if (tree) {
  96. return tree.children.map((item) => {
  97. return {
  98. value: item['dictValue'],
  99. label: item['name']
  100. }
  101. })
  102. }
  103. return []
  104. }
  105. // 生成UUID
  106. tool.snowyUuid = () => {
  107. let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
  108. let r = (Math.random() * 16) | 0,
  109. v = c === 'x' ? r : (r & 0x3) | 0x8
  110. return v.toString(16)
  111. })
  112. // 首字符转换成字母
  113. return 'xn' + uuid.slice(2)
  114. }
  115. tool.sortBy = (property) => {
  116. return function (value1, value2) {
  117. let a = value1[property]
  118. let b = value2[property]
  119. return a < b ? 1 : a > b ? -1 : 0
  120. }
  121. }
  122. tool.sortBy = (property, asc) => {
  123. //默认升序,不能写在闭包里面,写在闭包里面是无效的……asc没反应就
  124. if (asc === undefined) {
  125. asc = -1
  126. } else {
  127. asc = asc ? -1 : 1
  128. }
  129. return function (value1, value2) {
  130. let a = value1[property]
  131. let b = value2[property]
  132. return a < b ? asc : a > b ? asc * -1 : 0
  133. }
  134. }
  135. /**
  136. * 打开消息面板
  137. * @param type 类型,success,info,warning,error
  138. * @param message 标题
  139. * @param description 备注
  140. * @param duration 弹出时间,默认3s
  141. */
  142. export const showNotification = (type, message, description = '', duration = 3) => {
  143. notification[type]({
  144. message,
  145. description,
  146. duration
  147. })
  148. }
  149. // 文件处理工具end
  150. export default tool

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

  1. import 'dayjs/locale/zh-cn'
  2. export default {
  3. common: {
  4. searchButton: '查询',
  5. resetButton: '重置',
  6. addButton: '增加',
  7. editButton: '编辑',
  8. removeButton: '删除',
  9. batchRemoveButton: '批量删除',
  10. detailButton: '详情',
  11. searchKey: '关键词',
  12. imports: '导入',
  13. more: '更多',
  14. export: '导出',
  15. },
  16. model: {
  17. user: '用户',
  18. org: '机构',
  19. pos: '职位',
  20. role: '角色',
  21. bizUser: '人员'
  22. },
  23. login: {
  24. signInTitle: '用户登录',
  25. forgetPassword: '忘记密码',
  26. signIn: '登录',
  27. signInOther: '其他登录方式',
  28. accountPlaceholder: '请输入账号',
  29. accountError: '请输入账号',
  30. PWPlaceholder: '请输入密码',
  31. PWError: '请输入密码',
  32. validLaceholder: '请输入验证码',
  33. validError: '请输入验证码',
  34. accountPassword: '账号密码',
  35. phoneSms: '手机号登录',
  36. phonePlaceholder: '请输入手机号',
  37. smsCodePlaceholder: '请输入短信验证码',
  38. getSmsCode: '获取验证码',
  39. machineValidation: '机器验证',
  40. sendingSmsMessage: '短信发送中',
  41. newPwdPlaceholder: '请输入新密码',
  42. backLogin: '返回登录',
  43. restPassword: '重置密码',
  44. emailPlaceholder: '请输入邮箱号',
  45. emailCodePlaceholder: '请输入邮件验证码',
  46. restPhoneType: '手机号找回',
  47. restEmailType: '邮箱找回',
  48. sysName: '管理'
  49. },
  50. user: {
  51. userStatus: '用户状态',
  52. resetPassword: '重置密码',
  53. role: '角色',
  54. batchExportButton: '批量导出',
  55. grantRole: '授权角色',
  56. grantResource: '授权资源',
  57. grantPermission: '授权权限',
  58. exportUserInfo: '导出信息',
  59. placeholderNameAndSearchKey: '请输入姓名或关键词',
  60. placeholderUserStatus: '请选择状态',
  61. popconfirmDeleteUser: '确定要删除吗?',
  62. popconfirmResatUserPwd: '确定要重置吗?'
  63. }
  64. }
  1. export default {
  2. common: {
  3. searchButton: 'search',
  4. resetButton: 'reset',
  5. addButton: 'add',
  6. editButton: 'edit',
  7. removeButton: 'delete',
  8. batchRemoveButton: 'batch Remove',
  9. detailButton: 'detail',
  10. searchKey: 'Search Key',
  11. imports: 'Import',
  12. more: 'More',
  13. export: 'Export',
  14. },
  15. model: {
  16. user: 'user',
  17. org: 'org',
  18. pos: 'pos',
  19. role: 'role',
  20. bizUser: 'bizUser'
  21. },
  22. login: {
  23. signInTitle: 'Sign in',
  24. forgetPassword: 'Forget password',
  25. signIn: 'Sign in',
  26. signInOther: 'Sign in with',
  27. accountPlaceholder: 'Please input a user account',
  28. accountError: 'Please input a user account',
  29. PWPlaceholder: 'Please input a password',
  30. PWError: 'Please input a password',
  31. validLaceholder: 'Please input a valid',
  32. validError: 'Please input a valid',
  33. accountPassword: 'Account Password',
  34. phoneSms: 'Phone SMS',
  35. phonePlaceholder: 'Please input a phone',
  36. smsCodePlaceholder: 'Please input a SMS code',
  37. getSmsCode: 'SMS code',
  38. machineValidation: 'Machine Validation',
  39. sendingSmsMessage: 'Sending SMS Message',
  40. newPwdPlaceholder: 'Please input a new password',
  41. backLogin: 'Back Login',
  42. restPassword: 'Rest Password',
  43. emailPlaceholder: 'Please input a email',
  44. emailCodePlaceholder: 'Please input a Email code',
  45. restPhoneType: 'For phone rest',
  46. restEmailType: 'For email rest',
  47. sysName: 'management'
  48. },
  49. user: {
  50. userStatus: 'User Status',
  51. resetPassword: 'Reset Password',
  52. role: 'Role',
  53. batchExportButton: 'Batch Export',
  54. grantRole: 'Grant Role',
  55. grantResource: 'Grant Resource',
  56. grantPermission: 'Grant Permission',
  57. exportUserInfo: 'Export UserInfo',
  58. placeholderNameAndSearchKey: 'Please enter your name or keyword',
  59. placeholderUserStatus: 'Please select status',
  60. popconfirmDeleteUser: 'Are you sure you want to delete it?',
  61. popconfirmResatUserPwd: 'Are you sure you want to reset?'
  62. }
  63. }

二、配置页面

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

1. HTML内容

  1. <template>
  2. <div class="login_background">
  3. <div class="login_main">
  4. <div class="login_config">
  5. <a-dropdown>
  6. <global-outlined />
  7. <template #overlay>
  8. <a-menu>
  9. <a-menu-item
  10. v-for="item in lang"
  11. :key="item.value"
  12. :command="item"
  13. :class="{ selected: config.lang === item.value }"
  14. @click="configLang(item.value)"
  15. >
  16. {{ item.name }}
  17. a-menu-item>
  18. a-menu>
  19. template>
  20. a-dropdown>
  21. div>
  22. <div class="login-form">
  23. <a-card>
  24. <div class="login-header">
  25. <div class="logo">
  26. <img :alt="sysBaseConfig.SNOWY_SYS_NAME" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
  27. <label>{{ $t('login.sysName') }}label>
  28. div>
  29. div>
  30. <a-tabs v-model:activeKey="activeKey">
  31. <a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">
  32. <a-form ref="loginForm" :model="ruleForm" :rules="rules">
  33. <a-form-item name="account">
  34. <a-input
  35. v-model:value="ruleForm.account"
  36. :placeholder="$t('login.accountPlaceholder')"
  37. size="large"
  38. @keyup.enter="login"
  39. >
  40. <template #prefix>
  41. <UserOutlined class="login-icon-gray" />
  42. template>
  43. a-input>
  44. a-form-item>
  45. <a-form-item name="password">
  46. <a-input-password
  47. v-model:value="ruleForm.password"
  48. :placeholder="$t('login.PWPlaceholder')"
  49. size="large"
  50. autocomplete="off"
  51. @keyup.enter="login"
  52. >
  53. <template #prefix>
  54. <LockOutlined class="login-icon-gray" />
  55. template>
  56. a-input-password>
  57. a-form-item>
  58. <a-form-item name="validCode" v-if="captchaOpen === 'true'">
  59. <a-row :gutter="8">
  60. <a-col :span="17">
  61. <a-input
  62. v-model:value="ruleForm.validCode"
  63. :placeholder="$t('login.validLaceholder')"
  64. size="large"
  65. @keyup.enter="login"
  66. >
  67. <template #prefix>
  68. <verified-outlined class="login-icon-gray" />
  69. template>
  70. a-input>
  71. a-col>
  72. <a-col :span="7">
  73. <img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
  74. a-col>
  75. a-row>
  76. a-form-item>
  77. <a-form-item>
  78. <a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}?a>
  79. a-form-item>
  80. <a-form-item>
  81. <a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
  82. >{{ $t('login.signIn') }}
  83. a-button>
  84. a-form-item>
  85. a-form>
  86. a-tab-pane>
  87. a-tabs>
  88. a-card>
  89. div>
  90. div>
  91. div>
  92. template>

2. JS内容

  1. <style lang="less">
  2. @import 'login';
  3. style>

三、主要步骤

方法一

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

  1. <a-dropdown>
  2. <global-outlined />
  3. <template #overlay>
  4. <a-menu>
  5. <a-menu-item
  6. v-for="item in lang"
  7. :key="item.value"
  8. :command="item"
  9. :class="{ selected: config.lang === item.value }"
  10. @click="configLang(item.value)"
  11. >
  12. {{ item.name }}
  13. a-menu-item>
  14. a-menu>
  15. template>
  16. a-dropdown>

② 实现添加的小地球功能

  1. export default {
  2. data() {
  3. return {
  4. lang: [],
  5. config: {
  6. // lang 属性的值是通过 tool.data.get('APP_LANG') || this.$CONFIG.LANG 表达式获取的
  7. // 如果 tool.data.get('APP_LANG') 返回一个真值(非空、非undefined、非false等),则使用该值作为 lang 的值;否则,使用 this.$CONFIG.LANG 作为默认值。
  8. lang: tool.data.get('APP_LANG') || this.$CONFIG.LANG,
  9. }
  10. }
  11. },
  12. watch: { // 当 config.lang 发生变化时,即语言设置发生变化时,触发绑定的回调函数
  13. 'config.lang': function (val) {
  14. // 将新的语言设置应用到 $i18n 实例中,以改变应用程序的语言
  15. this.$i18n.locale = val
  16. // 将新的语言设置存储到 tool.data 中,以便在后续访问或导航到新页面时可以获取并应用语言设置
  17. tool.data.set('APP_LANG', val)
  18. }
  19. },
  20. methods: {
  21. // 更新 config.lang 的值
  22. configLang(key) {
  23. this.config.lang = key
  24. },
  25. }
  26. }

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

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

  1. lang: [
  2. {
  3. name: '简体中文',
  4. value: 'zh-cn'
  5. },
  6. {
  7. name: 'English',
  8. value: 'en'
  9. }
  10. ]
方法二

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

  1. <a-dropdown v-if="!ismobile" class="panel-item">
  2. <global-outlined />
  3. <template #overlay>
  4. <a-menu :selected-keys="lang">
  5. <a-menu-item key="zh-cn" @click="handleIn18('zh-cn')">
  6. <span>简体中文span>
  7. a-menu-item>
  8. <a-menu-item key="en" @click="handleIn18('en')">
  9. <span>Englishspan>
  10. a-menu-item>
  11. a-menu>
  12. template>
  13. a-dropdown>

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

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

四、多页面使用相同语言

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

方法一中

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

方法二中

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

lang 语言选择列表:

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

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

五、$t('') 无效

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

  1. <label>{{ $t('login.sysName') }}label>
  2. 只是用label举例并不表示只有label有用
  1. 以下是 :tab、:placeholder 的举例
  2. <a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">
  3. <a-form ref="loginForm" :model="ruleForm" :rules="rules">
  4. <a-form-item name="account">
  5. <a-input
  6. v-model:value="ruleForm.account"
  7. :placeholder="$t('login.accountPlaceholder')"
  8. size="large"
  9. @keyup.enter="login"
  10. >
  11. <template #prefix>
  12. <UserOutlined class="login-icon-gray" />
  13. template>
  14. a-input>
  15. a-form-item>
  16. <a-form-item name="password">
  17. <a-input-password
  18. v-model:value="ruleForm.password"
  19. :placeholder="$t('login.PWPlaceholder')"
  20. size="large"
  21. autocomplete="off"
  22. @keyup.enter="login"
  23. >
  24. <template #prefix>
  25. <LockOutlined class="login-icon-gray" />
  26. template>
  27. a-input-password>
  28. a-form-item>
  29. a-form>

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

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

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

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

zh-cn.js

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

en.js

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

HTML中

  1. <a-col :span="6" :key="shortcut.id" v-for="shortcut in shortcutList">
  2. <shortcutCard
  3. :icon="shortcut.icon ? shortcut.icon : 'menu-outlined'"
  4. :label="$t('menu.'+shortcut.title)"
  5. @click="leaveFor(shortcut.path)"
  6. />
  7. a-col>
  8. 其中 :label="$t('menu.'+shortcut.title)" 即引入menu中变量shortcut.title的值的数据

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

所以应用主要是:

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

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

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

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

  1. handleUser(key) {
  2. // 个人中心页面跳转
  3. if (key === 'uc') {
  4. router.push({ path: '/usercenter' })
  5. }
  6. // 点击清理缓存
  7. if (key === 'clearCache') {
  8. this.$confirm({
  9. // 提示
  10. title: this.$t('login.info'),
  11. // 提示内容
  12. content: this.$t('login.delCache'),
  13. icon: createVNode(ExclamationCircleOutlined),
  14. maskClosable: false,
  15. // 确认按钮
  16. okText: this.$t('button.sure'),
  17. // 取消按钮
  18. cancelText: this.$t('button.cancel'),
  19. onOk() {
  20. message.loading('正在清理中...', 1)
  21. tool.data.clear()
  22. setTimeout(() => {
  23. router.replace({ path: '/login' })
  24. location.reload()
  25. }, 100)
  26. },
  27. onCancel() {}
  28. })
  29. }
  30. // 退出登录
  31. if (key === 'outLogin') {
  32. this.$confirm({
  33. // 提示
  34. title: this.$t('login.info'),
  35. // 提示内容
  36. content: this.$t('login.logoutMessage'),
  37. icon: createVNode(ExclamationCircleOutlined),
  38. maskClosable: false,
  39. // 确认按钮
  40. okText: this.$t('button.sure'),
  41. // 取消按钮
  42. cancelText: this.$t('button.cancel'),
  43. onOk() {
  44. // 取得缓存中的token
  45. const token = tool.data.get('TOKEN')
  46. const param = {
  47. token: token
  48. }
  49. message.loading('退出中...', 1)
  50. loginApi
  51. .logout(param)
  52. .then(() => {
  53. // message.c
  54. // 清理掉个人的一些信息
  55. tool.data.remove('TOKEN')
  56. tool.data.remove('USER_INFO')
  57. tool.data.remove('MENU')
  58. tool.data.remove('PERMISSIONS')
  59. router.replace({ path: '/login' })
  60. })
  61. .catch(() => {
  62. tool.data.clear()
  63. router.replace({ path: '/login' })
  64. location.reload()
  65. })
  66. },
  67. onCancel() {}
  68. })
  69. }
  70. },

以下是调用 handleUser 方法的HTML:

  1. <a-menu>
  2. <a-menu-item key="uc" @click="handleUser('uc')">
  3. <UserOutlined style="margin-right: 8px" />
  4. <span>{{ $t('index.userCenter') }}span>
  5. a-menu-item>
  6. <a-menu-item key="clearCache" @click="handleUser('clearCache')">
  7. <loading3-quarters-outlined style="margin-right: 8px" />
  8. <span>{{ $t('index.cleanCache') }}span>
  9. a-menu-item>
  10. <a-menu-divider />
  11. <a-menu-item key="outLogin" @click="handleUser('outLogin')">
  12. <export-outlined style="margin-right: 8px" />
  13. <span>{{ $t('index.logout') }}span>
  14. a-menu-item>
  15. a-menu>

效果如图:

3、JS里的HTML部分中使用$t()
  1. renderAlert() {
  2. // 绘制统计列数据
  3. // eslint-disable-next-line no-unused-vars
  4. const needTotalItems = this.needTotalList.map((item) => {
  5. return (
  6. <span className="mr-3">
  7. {item.title} 总计{' '}
  8. <a className="font-6">{!item.customRender ? item.total : item.customRender(item.total)}a>
  9. span>
  10. )
  11. })
  12. // 绘制 清空 按钮
  13. // eslint-disable-next-line no-unused-vars
  14. const clearItem =
  15. typeof this.alert === 'boolean' && this.alert
  16. ? this.renderClear(this.clearSelected)
  17. : typeof this.alert.clear === 'function'
  18. ? this.renderClear(this.alert.clear)
  19. : null
  20. // 绘制 alert 组件
  21. if (alert) {
  22. const message = (
  23. <div>
  24. <span className="mr-3">
  25. 已选择 : <a className="font-6">{this.selectedRows.length}a>
  26. span>
  27. {needTotalItems}
  28. {clearItem}
  29. div>
  30. )
  31. return <a-alert showIcon class="mb-4" message={message} />
  32. }
  33. },
  34. renderClear(callback) {
  35. if (this.selectedRowKeys.length <= 0) return null
  36. return (
  37. <a
  38. className="ml-6"
  39. onClick={() => {
  40. callback()
  41. this.clearSelected()
  42. }}>
  43. {' '}
  44. 清空{' '}
  45. a>
  46. )
  47. },

切换多语言,修改代码:

  1. renderClear(callback) {
  2. if (this.selectedRowKeys.length <= 0) return null
  3. return (
  4. <a
  5. className="ml-6"
  6. onClick={() => {
  7. callback()
  8. this.clearSelected()
  9. }}>
  10. {' '}
  11. { this.$t('button.clean') }{' '}
  12. a>
  13. )
  14. },
  15. renderAlert() {
  16. // 绘制统计列数据
  17. // eslint-disable-next-line no-unused-vars
  18. const needTotalItems = this.needTotalList.map((item) => {
  19. return (
  20. <span className="mr-3">
  21. {item.title} 总计{' '}
  22. <a className="font-6">{!item.customRender ? item.total : item.customRender(item.total)}a>
  23. span>
  24. )
  25. })
  26. // 绘制 清空 按钮
  27. // eslint-disable-next-line no-unused-vars
  28. const clearItem =
  29. typeof this.alert === 'boolean' && this.alert
  30. ? this.renderClear(this.clearSelected)
  31. : typeof this.alert.clear === 'function'
  32. ? this.renderClear(this.alert.clear)
  33. : null
  34. // 绘制 alert 组件
  35. if (alert) {
  36. const message = (
  37. <div>
  38. <span className="mr-3">
  39. { this.$t('table.selected') } : <a className="font-6">{this.selectedRows.length}a>
  40. span>
  41. {needTotalItems}
  42. {clearItem}
  43. div>
  44. )
  45. return <a-alert showIcon class="mb-4" message={message} />
  46. }
  47. },

4、对antd的表头国际化i18n使用$t()

原始表格HTML:

  1. <s-table
  2. ref="table"
  3. :columns="columns"
  4. :data="loadData"
  5. :alert="options.alert.show"
  6. bordered
  7. :row-key="(record) => record.id"
  8. :tool-config="toolConfig"
  9. :row-selection="options.rowSelection"
  10. >
  11. <template #operator class="table-operator">
  12. <a-space>
  13. <a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('sysSeriesAdd')">
  14. <template #icon><plus-outlined />template>
  15. {{ $t('button.add') }}
  16. a-button>
  17. <xn-batch-delete
  18. v-if="hasPerm('sysSeriesBatchDelete')"
  19. :selectedRowKeys="selectedRowKeys"
  20. @batchDelete="deleteBatchSysSeries"
  21. />
  22. a-space>
  23. template>
  24. <template #bodyCell="{ column, record }">
  25. <template v-if="column.dataIndex === 'picUrl'">
  26. <img :src="record.picUrl" alt="图片" style="width: 80px; height: 100px">
  27. template>
  28. <template v-if="column.dataIndex === 'isOver'">
  29. {{ $TOOL.dictTypeData('COMMON_YES_OR_NO', record.isOver) }}
  30. template>
  31. <template v-if="column.dataIndex === 'online'">
  32. {{ $TOOL.dictTypeData('COMMON_YES_OR_NO', record.online) }}
  33. template>
  34. <template v-if="column.dataIndex === 'action'">
  35. <a-space>
  36. <a @click="batchBind(record)" v-if="hasPerm('sysSeriesBind')">{{ $t('button.bind') }}a>
  37. <a-divider type="vertical" v-if="hasPerm(['sysSeriesBind'], 'and')" />
  38. <a @click="formRef.onOpen(record)" v-if="hasPerm('sysSeriesEdit')">{{ $t('common.editButton') }}a>
  39. <a-divider type="vertical" v-if="hasPerm(['sysSeriesEdit', 'sysSeriesDelete'], 'and')" />
  40. <a-popconfirm :title="$t('user.popconfirmDeleteUser')" @confirm="deleteSysSeries(record)">
  41. <a-button type="link" danger size="small" v-if="hasPerm('sysSeriesDelete')">{{ $t('button.delete') }}a-button>
  42. a-popconfirm>
  43. a-space>
  44. template>
  45. template>
  46. s-table>

对表头以数组形式定义:

  1. const columns = [
  2. {
  3. title: '剧名',
  4. dataIndex: 'name'
  5. },
  6. {
  7. title: '总集数',
  8. dataIndex: 'totalVideo'
  9. },
  10. {
  11. title: '是否完结',
  12. dataIndex: 'isOver'
  13. },
  14. {
  15. title: '封面图',
  16. dataIndex: 'picUrl',
  17. },
  18. {
  19. title: '扩展信息',
  20. dataIndex: 'extJson',
  21. ellipsis: true
  22. },
  23. {
  24. title: '是否上架',
  25. dataIndex: 'online'
  26. },
  27. {
  28. title: '创建时间',
  29. dataIndex: 'createTime'
  30. },
  31. {
  32. title: '创建用户',
  33. dataIndex: 'createrName'
  34. }
  35. ]

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

如图:再:const { t } = i18n.global;,

代码如下:

切换后刷新如下图:

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

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

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

  1. const columns = [
  2. {
  3. title: t('table.seriesName'),
  4. dataIndex: 'name',
  5. },
  6. {
  7. title: t('table.allPlay'),
  8. dataIndex: 'totalVideo'
  9. },
  10. {
  11. title: t('table.isOver'),
  12. dataIndex: 'isOver'
  13. },
  14. {
  15. title: t('table.image'),
  16. dataIndex: 'picUrl',
  17. },
  18. {
  19. title: t('form.expand'),
  20. dataIndex: 'extJson',
  21. ellipsis: true
  22. },
  23. {
  24. title: t('table.isOn'),
  25. dataIndex: 'online'
  26. },
  27. {
  28. title: t('table.createTime'),
  29. dataIndex: 'createTime'
  30. },
  31. {
  32. title: t('table.createUser'),
  33. dataIndex: 'createrName'
  34. }
  35. ]

将判断部分也进行修改:

  1. <template #bodyCell="{ column, record }">
  2. <template v-if="column.dataIndex === 'picUrl'">
  3. <img :src="record.picUrl" alt="图片" style="width: 80px; height: 100px">
  4. template>
  5. <template v-if="column.dataIndex === 'isOver'">
  6. <div v-if="record.isOver === 'YES'">{{ $t('table.yes') }}div>
  7. <div v-else>{{ $t('table.no') }}div>
  8. template>
  9. <template v-if="column.dataIndex === 'online'">
  10. <div v-if="record.online === 'YES'">{{ $t('table.yes') }}div>
  11. <div v-else>{{ $t('table.no') }}div>
  12. template>
  13. template>
5、关于setup函数中的i18n的使用

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

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

之后所有的需要 $t 或者 this.$t 的地方都使用 t 即可。

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索