当前位置:   article > 正文

vue3 实现动态切换语言

vue3 实现动态切换语言

动态切换语言

动态语言切要做两件事,一种是切换自定义语言,另一种是切换ui框架语言,自定义语言使用i18n,ui框架使用elementplus自带的Config Provider 全局配置
所谓动态切换就是不使用location.reload()来重启刷新页面,来切换语言,
语言的初始值:先查看本地存在中lang有没有值,如果有就使用本地存储的lang作为初始值,否则使用浏览器语言,下面i18n/index.js 中的 getLang方法获取浏览器语言,getItme获取本地存储语言 (这里省略代码),每次修改都要重新更新本地存储的lang值

1.自定义组件

(1) 创建一个文件,i18n/index.js

import mZhLocale from './lang/zh' // 中文语言包
import mEnLocale from './lang/en'  // 英语语言包
import getLang from "../utilities/BrowserLang" // 获取浏览器的语言
import  {getItem}        from "../utilities/Storage" // 获取本地存储设置的语言
import  { LANG } from "../utilities/Constant"
const messages = {
  en: {
    msg: {
      // test:"hello word!"
        ...mEnLocale
    }
  },
  zh: {
    msg: {
      ...mZhLocale,
      // test:"世界你好"
    }
  }
}
// 使用
//  <div class=""> {{ $t('msg.test') }}</div>

let locale ='zh'
if(getItem(LANG))
{
  locale=getItem(LANG)
}
else if(getLang())
{
  locale=getLang()
}
//1.组件的模板中使用 $t()
//2.组件的js使用 i18n.t
//3.非组件中使用i18n.global.t
//4.切换组件还是要
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  // 使用 Composition API 模式,则需要将其设置为false
  legacy: false,
  // 全局注入 $t 函数
  globalInjection: true,
  locale,
  messages,
  // 防止使用v-html=“$t(“”)”的xss警告
  warnHtmlMessage: false
})

export default i18n
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

(2)在main.js中安装i18n

import i18n from './i18n/index.js'
app.use(i18n)
  • 1
  • 2

(3)组件中访问i18n实现切换自定义语言

<template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item :disabled='language==="zh"' @click='language==="zh"?"null":handleSetLanguage("zh")'>中文</el-dropdown-item>
          <el-dropdown-item :disabled='language==="en"' @click='language==="en"?"null":handleSetLanguage("en")'>English</el-dropdown-item>
        </el-dropdown-menu>
      </template>

<script setup >
import { useI18n } from 'vue-i18n'
//import { defineProps, computed,getCurrentInstance} from 'vue'

const i18n = useI18n()
const handleSetLanguage = lang => {

  // 切换自定义语言
  i18n.locale.value = lang

  // 切换element-plus语言
//  Instance?.proxy?.$mitt?.emit("changLanguage",lang)


  // 修改本地语言
  //Language.setLanguage(lang)


  ElMessage({
    showClose: true,
    message: i18n.t("msg.toast.switchLangSuccess"),
    type: 'success',
  })

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

其中最重要的是i18n.locale.value = lang 修改locala的值"zh"或者"en"来动态改变,

2 vue3中使用i18n自定义语言的方法

中文语言包例子

export default {
  login: {
    title: 'User Login',
    loginBtn: 'Login',
    usernameRule: 'Username is required',
    passwordRule: 'Password cannot be less than 6 digits',
    。。。。。
  },
  。。。。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(1)组件的template模板中 使用 $t(“”)

 <h1>{{ $t('msg.login.title') }}
 :placeholder="$t('msg.login.usernameT')" 
  • 1
  • 2

注意属性要是有v-bind,不用导入任何东西就直接可以使用
(2) 组件的js中使用 ,使用i18n.t函数


import { useI18n } from "vue-i18n";
let i18n=useI18n()


    ElMessage({
            showClose: true,
            message: i18n.t('msg.login.loginError'),
            type: 'error'
          })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

(3)在非组件中使用,在非组件中使用例如roter中,需要使用createI18n()创建的
及上文的i18n/index.js 函数
例如下面的是将router中的中meta中的title切换
使用i18n.global.t(“msg.route.”+title)
i18n.js

import i18n from "../i18n/index"
export default  function generateTitle(title)
{
return i18n.global.t("msg.route."+title)
}
  • 1
  • 2
  • 3
  • 4
  • 5

使用title作为菜单

// 使用
<span>{{generateTitle(menuItem.meta.title)}}</span> 

import generateTitle from "../../../utilities/i18n" //导入函数
  • 1
  • 2
  • 3
  • 4

先用路由获取title值,再由title获取对应的语言,如果再router中直接使用
i18n.global.t("msg.route.xxxx")
来替换title会导致不能动态切换,只能刷新页面切换

3.elementPlus的语言切换

(1)app.vue

<template>
  <el-config-provider :locale="locale">
    <router-view></router-view>
  </el-config-provider>
</template>

<script setup>
import { computed, ref } from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
const language = ref('zh-cn')
const locale =ref(zhCn)  //computed(() => (language.value === 'zh-cn' ? zhCn : en))

import  { getCurrentInstance } from "vue"
let Instance=getCurrentInstance();

// 让子组件传递值过来切换语言
Instance?.proxy?.$mitt.on("changLanguage",(para)=>{
  if(para==="zh")
  {
    locale.value=zhCn
  }
  if(para==="en")
  {
    locale.value=en
  }
})
</script>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

其中最重要的是修改locale值为zhCn或者en ,其中Instance?.proxy?.$mitt.on这个是mitt,给子组件提供修改App.vue,的订阅

(2)子组件中切换element-plus


<script setup >

import { defineProps, computed,getCurrentInstance} from 'vue'
import { ElMessage } from 'element-plus'


let Language=useLanguageStore()
let language = computed(() => Language.language)
let Instance=getCurrentInstance();

// 点击切换语言
const handleSetLanguage = lang => {
  // 切换自定义语言
 // i18n.locale.value = lang
 
  // 切换element-plus语言
  
  // 给父组件发送消息
  Instance?.proxy?.$mitt?.emit("changLanguage",lang)
  
  // 修改本地语言
  Language.setLanguage(lang)
  ElMessage({
    showClose: true,
    message: i18n.t("msg.toast.switchLangSuccess"),
    type: 'success',
  })
    // location.reload();//

}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

这其中最重要的是给父代组件(App.vue)发送修改他`locale值的消息

我们同时修改,自定义语言,和UI语言,就可以修改全部语言了,修改之后,当前语言状态保存到本地存储

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/332189
推荐阅读
相关标签
  

闽ICP备14008679号