国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言

這篇具有很好參考價(jià)值的文章主要介紹了vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

需求:后臺(tái)管理系統(tǒng),可以實(shí)現(xiàn)語(yǔ)言切換

實(shí)現(xiàn)過(guò)程:用的i18n來(lái)實(shí)現(xiàn)的語(yǔ)言切換,網(wǎng)上能看到好多模板,根據(jù)自己的需求,修改一下即可使用,大概都是差不多的,因?yàn)樯婕暗胶蠖?,所以要跟后端協(xié)商一致決定去寫(xiě),我的設(shè)計(jì)思路是跟著后端設(shè)計(jì)更改的,如下:

1.語(yǔ)言是后端接口返回的,不是前端寫(xiě)死的(eg:中文、English),由于我的切換語(yǔ)言,設(shè)計(jì)到了兩個(gè)地方,一個(gè)是登錄頁(yè)面,一個(gè)是登錄之后的頁(yè)面,后端不能給一個(gè)接口,要區(qū)分兩個(gè)接口給前端,所以關(guān)于這個(gè)需求,前端自己加了判斷(如果你們后端給一個(gè)接口,則可忽略我寫(xiě)的判斷)

2.根據(jù)自己選擇的哪一種語(yǔ)言,需要通過(guò)接口傳給后端,后端會(huì)將其存到某個(gè)用戶表里,這個(gè)接口也是兩個(gè),也需寫(xiě)判斷

3.如果用戶是從來(lái)沒(méi)有選擇過(guò)語(yǔ)言的用戶,則前端需要規(guī)定默認(rèn)語(yǔ)言,且要與后端的默認(rèn)語(yǔ)言保持一致,于是和后端協(xié)商一致決定,其默認(rèn)語(yǔ)言是后端返回的語(yǔ)言的第一個(gè)

4.如果后端有選擇是哪個(gè)語(yǔ)言,我們將其傳給了后端,后端講其存入了用戶表,用戶登錄之后,會(huì)在用戶接口里,返回給我們,我們將其存 localStorage,這時(shí)候,就算用戶再次退出到登錄頁(yè)面,我們就可以將用戶默認(rèn)語(yǔ)言做一個(gè)判斷,判斷存入localStorage的language是否有值,如果有值,則登錄頁(yè)面的語(yǔ)言取localStorage的language,如果沒(méi)有,則還是取后端語(yǔ)言接口返回的第一個(gè)值,這樣,就可以把用戶已經(jīng)選擇過(guò)的語(yǔ)言,在登錄頁(yè)面也能進(jìn)行判斷用戶習(xí)慣

文檔:?vue-i18n

一.安裝vue-i18n?

npm install vue-i18n

二.在mian.js引入

//i18n
import i18n from "@/lang";
Vue.use(Element,{
  size:Cookies.get('size') || 'small',
  i18n:(key,value)=>i18n.t(key,value)
})
new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})

三.在src下創(chuàng)建一個(gè)lang文件夾,其中包括en.js、zh.js、index.js文件

1.src/lang/en.js

export default {
  login: {
    username:'username',//用戶名
    password:'password',//密碼
    code:'code',//驗(yàn)證碼
    login:'login',//登錄
    logging: 'logging...',//登錄...
    storage:'remember the password',//記住密碼
  },
  home:{
    welcome:'Welcome to use',//歡迎使用
  },
  route:{
    homepage:'Home page',//首頁(yè)
    profile:'Profile',//個(gè)人中心
    系統(tǒng)管理:"system manage",//系統(tǒng)管理
    系統(tǒng)監(jiān)控:'system monitor',
    系統(tǒng)工具:"system tools",
    創(chuàng)建運(yùn)單:"create waybill",
    批量運(yùn)單:'waybill batch',
    運(yùn)單管理:"waybill manage",
    審核管理:'audits manage',
    充值管理:'recharge manage',
    失敗訂單詳情:'failed order details',
    運(yùn)費(fèi)管理:'freight manage',
    賬單管理:'bill manage',
    倉(cāng)庫(kù)管理:'warehouse manage',
    用戶管理:'user query',
    角色管理:'user query',
    菜單管理:'menu manage',
    部門(mén)管理:'dept manage',
    崗位管理:'position manage',
    字典管理:'dictionary manage',
    參數(shù)設(shè)置:'parameter settings',
    通知公告:'notice announcent',
    日志管理:'log manage',
    操作日志:'operation log',
    登錄日志:'login log',
    在線用戶:'online users',
    定時(shí)任務(wù):'scheduled tasks',
    數(shù)據(jù)監(jiān)控:'data monitor',
    服務(wù)監(jiān)控:'service monitor',
    運(yùn)單審核:'audits order',
    充值審核:'audits recharge',
    客戶充值:'customer recharge',
    我的充值:'my recharge',
    基礎(chǔ)運(yùn)費(fèi):'basic freight',
    其他附加費(fèi):'other surcharges',
    燃油附加費(fèi):'fuel surcharge',
    旺季附加費(fèi):'peak surcharge',
    全部賬單:'bill whole',
    我的賬單:'bill my',
    訂單詳情:'order details',
    倉(cāng)庫(kù)配置:'warehouse configuration',
    基礎(chǔ)成本價(jià):'basic cost',
    其他成本價(jià):'other cost',
    旺季成本價(jià):'peak cost',
    查詢:'query',
    新增:'add',
    修改:'alter',
    導(dǎo)入:'import',
    導(dǎo)出:'export',
    刪除:'remove',
    重置密碼:'reset passwords',
    倉(cāng)庫(kù):'warehouse',
    批量強(qiáng)退:'batch forcing',
    單條強(qiáng)退:'single strong back',
    眾拓網(wǎng)通官網(wǎng):'Zhongtuo Netcom official website',
    下載失敗訂單:'download failed order',
    下載面單:'download sheet',
    客戶查詢:'customer query',
    已取消導(dǎo)出:'export cancelled',
    取消審核中導(dǎo)出:'export cancel audit',
    審核:'audit',
    審核平賬:'audit and balance accounts',
    審核平賬明細(xì):'review the balance of accounts details',
    充值:'top up',
    充值記錄:'recharge record',
    消費(fèi)記錄:'expense calendar',
    補(bǔ)交憑證:'resubmit documents',
    回顯:'echo',
    審核明細(xì):'audit detail',
    充值明細(xì):'top-up details',
    失敗訂單詳情查詢:'failed order details query',
    復(fù)制:'copy',
    基礎(chǔ)運(yùn)費(fèi)列表:'base freight list',
    客戶列表:'customer list',
  },
}

?2.src/lang/zh.js

export default {
  login: {
    username:'用戶名',//用戶名
    password:'密碼',//密碼
    code:'驗(yàn)證碼',//驗(yàn)證碼
    login:'登錄',//登錄
    logging: '登錄...',//登錄...
    storage:'記住密碼',//記住密碼
  },
  home:{
    welcome:'歡迎使用',//歡迎使用
  },
  route:{
    homepage:'首頁(yè)',//首頁(yè)
    profile:'個(gè)人中心',//個(gè)人中心
    系統(tǒng)管理:"系統(tǒng)管理",//系統(tǒng)管理
    系統(tǒng)監(jiān)控:'系統(tǒng)監(jiān)控',
    系統(tǒng)工具:"系統(tǒng)工具",
    創(chuàng)建運(yùn)單:"創(chuàng)建運(yùn)單",
    批量運(yùn)單:'批量運(yùn)單',
    運(yùn)單管理:"運(yùn)單管理",
    審核管理:'審核管理',
    充值管理:'充值管理',
    失敗訂單詳情:'失敗訂單詳情',
    運(yùn)費(fèi)管理:'運(yùn)費(fèi)管理',
    賬單管理:'賬單管理',
    倉(cāng)庫(kù)管理:'倉(cāng)庫(kù)管理',
    用戶管理:'用戶管理',
    角色管理:'角色管理',
    菜單管理:'菜單管理',
    部門(mén)管理:'部門(mén)管理',
    崗位管理:'崗位管理',
    字典管理:'字典管理',
    參數(shù)設(shè)置:'參數(shù)設(shè)置',
    通知公告:'通知公告',
    日志管理:'日志管理',
    操作日志:'操作日志',
    登錄日志:'登錄日志',
    在線用戶:'在線用戶',
    定時(shí)任務(wù):'定時(shí)任務(wù)',
    數(shù)據(jù)監(jiān)控:'數(shù)據(jù)監(jiān)控',
    服務(wù)監(jiān)控:'服務(wù)監(jiān)控',
    運(yùn)單審核:'運(yùn)單審核',
    充值審核:'充值審核',
    客戶充值:'客戶充值',
    我的充值:'我的充值',
    基礎(chǔ)運(yùn)費(fèi):'基礎(chǔ)運(yùn)費(fèi)',
    其他附加費(fèi):'其他附加費(fèi)',
    燃油附加費(fèi):'燃油附加費(fèi)',
    旺季附加費(fèi):'旺季附加費(fèi)',
    全部賬單:'全部賬單',
    我的賬單:'我的賬單',
    訂單詳情:'訂單詳情',
    倉(cāng)庫(kù)配置:'倉(cāng)庫(kù)配置',
    基礎(chǔ)成本價(jià):'基礎(chǔ)成本價(jià)',
    其他成本價(jià):'其他成本價(jià)',
    旺季成本價(jià):'旺季成本價(jià)',
    查詢:'查詢',
    新增:'新增',
    修改:'修改',
    導(dǎo)入:'導(dǎo)入',
    導(dǎo)出:'導(dǎo)出',
    刪除:'刪除',
    重置密碼:'重置密碼',
    倉(cāng)庫(kù):'倉(cāng)庫(kù)',
    批量強(qiáng)退:'批量強(qiáng)退',
    單條強(qiáng)退:'單條強(qiáng)退',
    眾拓網(wǎng)通官網(wǎng):'眾拓網(wǎng)通官網(wǎng)',
    下載失敗訂單:'下載失敗訂單',
    下載面單:'下載面單',
    客戶查詢:'客戶查詢',
    已取消導(dǎo)出:'已取消導(dǎo)出',
    取消審核中導(dǎo)出:'取消審核中導(dǎo)出',
    審核:'審核',
    審核平賬:'審核平賬',
    審核平賬明細(xì):'審核平賬明細(xì)',
    充值:'充值',
    充值記錄:'充值記錄',
    消費(fèi)記錄:'消費(fèi)記錄',
    補(bǔ)交憑證:'補(bǔ)交憑證s',
    回顯:'回顯',
    審核明細(xì):'審核明細(xì)',
    充值明細(xì):'充值明細(xì)',
    失敗訂單詳情查詢:'失敗訂單詳情查詢',
    復(fù)制:'復(fù)制',
    基礎(chǔ)運(yùn)費(fèi)列表:'基礎(chǔ)運(yùn)費(fèi)列表',
    客戶列表:'客戶列表',
  },
}

??3.src/lang/index.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import Cookies from 'js-cookie'
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
import enLocale from './en'
import zhLocale from './zh'

Vue.use(VueI18n)

const messages = {
  en: {
    ...enLocale,
    ...elementEnLocale
  },
  zh: {
    ...zhLocale,
    ...elementZhLocale
  }
}
export function getLanguage() {
  const chooseLanguage = Cookies.get('language')
  if (chooseLanguage) return chooseLanguage
  return 'en'
}
const i18n = new VueI18n({
  locale: getLanguage(),
  messages
})

export default i18n

三.在src/components下創(chuàng)建到LangSelect/index.vue文件(語(yǔ)言切換組件)

<script src="../../api/login.js"></script>
<template>
  <el-dropdown trigger="click" class="international" @command="handleSetLanguage">
    <div>
      <svg-icon class-name="international-icon" icon-class="language" />
    </div>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item  v-for="item in languagelist"  :disabled="$i18n.locale===item.language" :command={languageId:item.languageId,language:item.language}>
        {{item.name}}
      </el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</template>

<script>
import {checkLanguage, languagelist} from "@/api/menu";
import item from "@/layout/components/Sidebar/Item.vue";
import {languagelistt,checkLanguagee} from '@/api/login'

export default {
  props:{
    //標(biāo)記他是那個(gè)頁(yè)面過(guò)來(lái)的,是logo頁(yè)面,還是登錄之后的主頁(yè)面
    orientation:{
      type:Number,
      default:0
    }
  },
  data(){
    return{
      languagelist:[],
      lang:null,
    }
  },
  computed: {
    item() {
      return item
    },
    language() {
      return this.$store.getters.language
    }
  },
  created() {
    this.getlanguelist()
  },
  methods: {
    //這個(gè)是獲取后端返回的語(yǔ)言接口
    getlanguelist(){
      //login頁(yè)面語(yǔ)言接口,接口有兩個(gè),但是接口性質(zhì)是一樣的,都是返回語(yǔ)言接口,只不過(guò)是一個(gè)在登錄頁(yè)面的,一個(gè)是登錄之后主頁(yè)面的(如果你們后端返回一個(gè)接口,九不用去寫(xiě)這個(gè)判斷了)
      if(this.orientation==1){
        languagelistt().then((res)=>{
          this.languagelist=res.data
          //拿取user接口存的language,如果有就拿user存的language,如果沒(méi)有就取后端接口返回的第一個(gè)
          const language=localStorage.getItem('language') ||res.data[0].language
          this.$store.dispatch('app/setLanguage', language)
          this.$i18n.locale=language
        })
      }else {
        //主頁(yè)面語(yǔ)言接口
        languagelist().then((res)=>{
          this.languagelist=res.data
          const language=localStorage.getItem('language')
          this.$store.dispatch('app/setLanguage', language)
          this.$i18n.locale=localStorage.getItem('language')
        })
      }
    },
    handleSetLanguage(lang) {//點(diǎn)擊切換事件
      this.$i18n.locale = lang.language
      this.$store.dispatch('app/setLanguage', lang.language)
      this.checkLanguage(lang.languageId)
      this.$message({
        message: 'Switch Language Success',
        type: 'success'
      })
    },
    //傳給后端,后端標(biāo)記是什么語(yǔ)言
    checkLanguage(item){
      //login頁(yè)面
      if(this.orientation==1){
        checkLanguagee(item).then((res)=>{
          // 傳值給前端,前端再把獲取到的值,傳到login接口里面
          this.$emit("languageid",res.data.languageId)
        })
      }else {
        //主頁(yè)面
        checkLanguage(item).then((res)=>{
          this.updatePermission()
        })
      }
    },
  }
}
</script>

四.在src/store/modules/app.js?里將language存入vuex和cookie

import Cookies from 'js-cookie'
import { getLanguage } from '@/lang/index'

const state = {
  sidebar: {
    opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
    withoutAnimation: false,
    hide: false
  },
  device: 'desktop',
  language: getLanguage(),
  size: Cookies.get('size') || 'medium'
}

const mutations = {
  TOGGLE_SIDEBAR: state => {
    if (state.sidebar.hide) {
      return false;
    }
    state.sidebar.opened = !state.sidebar.opened
    state.sidebar.withoutAnimation = false
    if (state.sidebar.opened) {
      Cookies.set('sidebarStatus', 1)
    } else {
      Cookies.set('sidebarStatus', 0)
    }
  },
  CLOSE_SIDEBAR: (state, withoutAnimation) => {
    Cookies.set('sidebarStatus', 0)
    state.sidebar.opened = false
    state.sidebar.withoutAnimation = withoutAnimation
  },
  TOGGLE_DEVICE: (state, device) => {
    state.device = device
  },
//語(yǔ)言
  SET_LANGUAGE: (state, language) => {
    state.language = language
    Cookies.set('language', language)
  },
  SET_SIZE: (state, size) => {
    state.size = size
    Cookies.set('size', size)
  },
  SET_SIDEBAR_HIDE: (state, status) => {
    state.sidebar.hide = status
  }
}

const actions = {
  toggleSideBar({ commit }) {
    commit('TOGGLE_SIDEBAR')
  },
  closeSideBar({ commit }, { withoutAnimation }) {
    commit('CLOSE_SIDEBAR', withoutAnimation)
  },
  toggleDevice({ commit }, device) {
    commit('TOGGLE_DEVICE', device)
  },
//語(yǔ)言
  setLanguage({ commit }, language) {
    commit('SET_LANGUAGE', language)
  },
  setSize({ commit }, size) {
    commit('SET_SIZE', size)
  },
  toggleSideBarHide({ commit }, status) {
    commit('SET_SIDEBAR_HIDE', status)
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

五.src/modules/user.js,將后端用戶信息接口返回的language存入localStorage里

import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'

const user = {
  state: {
    token: getToken(),
    name: '',
    avatar: '',
    roles: [],
    permissions: [],
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token
    },
    SET_NAME: (state, name) => {
      state.name = name
    },
    SET_AVATAR: (state, avatar) => {
      state.avatar = avatar
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles
    },
    SET_PERMISSIONS: (state, permissions) => {
      state.permissions = permissions
    },
  },

  actions: {
    // 登錄
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim()
      const password = userInfo.password
      const code = userInfo.code
      const uuid = userInfo.uuid
      //語(yǔ)言
      const languageId=userInfo.languageId
      return new Promise((resolve, reject) => {
        login(username, password, code, uuid,languageId).then(res => {
          setToken(res.token)
          commit('SET_TOKEN', res.token)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 獲取用戶信息
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo(state.token).then(res => {
          const user = res.user
          const avatar = user.avatar == "" ? require("@/assets/image/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
          if (res.roles && res.roles.length > 0) { // 驗(yàn)證返回的roles是否是一個(gè)非空數(shù)組
            commit('SET_ROLES', res.roles)
            commit('SET_PERMISSIONS', res.permissions)
            sessionStorage.setItem('infoCustomers',JSON.stringify(res.customers))
            sessionStorage.setItem('infouser',JSON.stringify(res.user.roles))
            //注:用戶已進(jìn)入頁(yè)面,調(diào)用到用戶接口,將用戶接口里面的語(yǔ)言存儲(chǔ)到localStorage,可以方便用戶在登錄頁(yè)面的時(shí)候判斷語(yǔ)言是中文還是英文(登錄頁(yè)面語(yǔ)言應(yīng)與user接口保持一直)
            localStorage.setItem('language',JSON.stringify(res.user.language.language).replace(/\"/g, ""))
          } else {
            commit('SET_ROLES', ['ROLE_DEFAULT'])
          }
          commit('SET_NAME', user.userName)
          commit('SET_AVATAR', avatar)
          resolve(res)
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 退出系統(tǒng)
    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        logout(state.token).then(() => {
          commit('SET_TOKEN', '')
          commit('SET_ROLES', [])
          commit('SET_PERMISSIONS', [])
          removeToken()
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 前端 登出
    FedLogOut({ commit }) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '')
        removeToken()
        resolve()
      })
    }
  }
}

export default user

?六.登錄頁(yè)面

?效果圖:

1.en:

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

2.English:

?vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

<template>
  <div class="login">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
      <div class="titlebox">
        <h3 class="title">{{setName}}</h3>
        <lang-select class="set-language"  @languageid="handlelanguage" :orientation='orientation'/>
      </div>
      <el-form-item prop="username">
        <el-input v-model="loginForm.username" type="text" auto-complete="off" :placeholder="$t('login.username')">
          <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
          v-model="loginForm.password"
          type="password"
          auto-complete="off"
          :placeholder="$t('login.password')"
          @keyup.enter.native="handleLogin"
        >
          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
        </el-input>
      </el-form-item>
      <el-form-item prop="code">
        <el-input
          v-model="loginForm.code"
          auto-complete="off"
          :placeholder="$t('login.code')"
          style="width: 63%"
          @keyup.enter.native="handleLogin"
        >
          <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
        </el-input>
        <div class="login-code">
          <img :src="codeUrl" @click="getCode" class="login-code-img"/>
        </div>
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">{{$t('login.storage')}}</el-checkbox>
      <el-form-item style="width:100%;">
        <el-button
          :loading="loading"
          size="medium"
          type="primary"
          style="width:100%;"
          @click.native.prevent="handleLogin"
        >
          <span v-if="!loading">{{$t('login.login')}}</span>
          <span v-else>{{$t('login.logging')}}</span>
        </el-button>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <span>Copyright ? 2021-2022 xxx All Rights Reserved 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證:<a
         target="_blank">xxxxx</a></span>
    </div>
  </div>
</template>

<script>
import {getCodeImg, login} from "@/api/login";
import Cookies from "js-cookie";
import {decrypt, encrypt} from '@/utils/jsencrypt'
import langSelect from "@/components/LangSelect/index.vue";
import {config} from "@/api/menu";
import {mapGetters, mapState} from "vuex";

export default {
  name: "Login",
  components:{
    langSelect
  },
  data() {
    return {
      orientation:1,
      codeUrl: "",
      cookiePassword: "",
      loginForm: {
        username: "admin",
        password: "",
        rememberMe: false,
        code: "",
        uuid: "",
        languageId:"",
      },
      loginRules: {
        username: [
          { required: true, trigger: "blur", message: this.$t('rules.rulesusername') }
        ],
        password: [
          { required: true, trigger: "blur", message: this.$t('rules.rulespassword')  }
        ],
        code: [{ required: true, trigger: "change", message: this.$t('rules.rulescode') }]
      },
      loading: false,
      redirect: undefined,
      title:"",
    };
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect;
      },
      immediate: true
    },
    //監(jiān)聽(tīng)語(yǔ)言的改變,實(shí)時(shí)改變校驗(yàn)
    language(newVal, oldVal){
      this.loginRules={
        username: [
          { required: true, trigger: "blur", message: this.$t('rules.rulesusername') }
        ],
          password: [
          { required: true, trigger: "blur", message: this.$t('rules.rulespassword')  }
        ],
          code: [{ required: true, trigger: "change", message: this.$t('rules.rulescode') }]
      }
    }
  },
  created() {
    this.getCode();
    this.getCookie();
    this.getproject()
  },
  computed:{
    ...mapGetters(['getSetName']),
    setName() {
      return this.getSetName || this.title
    },
    ...mapState({
      language: state => state.app.language
    })
  },
  methods: {
    //獲取項(xiàng)目名字接口
    getproject(){
      config().then((res)=>{
        this.title=res.msg
      })
    },
    login,
    handlelanguage(name){
      this.loginForm.languageId=name
    },
    //獲取驗(yàn)證碼
    getCode() {
      getCodeImg().then(res => {
        this.codeUrl = "data:image/gif;base64," + res.img;
        this.loginForm.uuid = res.uuid;
      });
    },
    getCookie() {
      const username = Cookies.get("username");
      const password = Cookies.get("password");
      const rememberMe = Cookies.get('rememberMe')
      this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        password: password === undefined ? this.loginForm.password : decrypt(password),
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
      };
    },
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true;
          if (this.loginForm.rememberMe) {
            Cookies.set("username", this.loginForm.username, { expires: 30 });
            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
          } else {
            Cookies.remove("username");
            Cookies.remove("password");
            Cookies.remove('rememberMe');
          }
          this.$store
            .dispatch("Login", this.loginForm)
            .then(() => {
              this.$router.push({ path: this.redirect || "/" });
            })
            .catch(() => {
              this.loading = false;
              this.getCode();
            });
        }
      });
    }
  }
};
</script>

? 七.在utils里面新建一個(gè)i18n.js

export function generateTitle(title) {
  const hasKey = this.$te('route.' + title)
  if (hasKey) {
    // $t :this method from vue-i18n, inject in @/lang/index.js
    const translatedTitle = this.$t('route.' + title)
    return translatedTitle
  }
  return title
}

?七.根據(jù)語(yǔ)言的切換,面包屑的語(yǔ)言也隨之更新,src/components/Breadcrumb文件里

1.zh:?

?vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

2.en:?

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端?

<template>
<!--  這個(gè)是上面的面包屑-->
  <el-breadcrumb class="app-breadcrumb" separator="/">
    <transition-group name="breadcrumb">
      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">
<!--          {{ $t(`route.${item.meta.title}`) }}-->
          {{generateTitle(item.meta.title)}}
        </span>
        <a v-else @click.prevent="handleLink(item)">
<!--          {{ $t(`route.${item.meta.title}`)}}-->
          {{generateTitle(item.meta.title)}}
        </a>
      </el-breadcrumb-item>
    </transition-group>
  </el-breadcrumb>
</template>

<script>
import pathToRegexp from 'path-to-regexp'
import { generateTitle } from '@/utils/i18n'
export default {
  inject:['reload'],
  data() {
    return {
      levelList: null
    }
  },
  watch: {
    $route(route) {
      // if you go to the redirect page, do not update the breadcrumbs
      if (route.path.startsWith('/redirect/')) {
        return
      }
      this.getBreadcrumb()
    },
  },
  created() {
    this.getBreadcrumb()
  },

  methods: {
    generateTitle,
    getBreadcrumb() {
      // only show routes with meta.title
      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
      const first = matched[0]
      if (!this.isDashboard(first)) {
        matched = [{ path: '/index', meta: { title: 'homepage' }}].concat(matched)
      }
      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
    },
    isDashboard(route) {
      const name = route && route.name
      if (!name) {
        return false
      }
      return name.trim() === 'Home page'
    },
    pathCompile(path) {
      const { params } = this.$route
      var toPath = pathToRegexp.compile(path)
      return toPath(params)
    },
    handleLink(item) {
      const { redirect, path } = item
      if (redirect) {
        this.$router.push(redirect)
        return
      }
      this.$router.push(this.pathCompile(path))
    }
  }
}
</script>

<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
  display: inline-block;
  font-size: 14px;
  line-height: 50px;
  margin-left: 8px;

  .no-redirect {
    color: #97a8be;
    cursor: text;
  }
}
</style>

八.src\layout\components\Sidebar\SidebarItem.vue文件

1.zh? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

2.en

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

我用的是若依后臺(tái)管理系統(tǒng)框架,對(duì)于路由是后端接口返回的,所以,路由語(yǔ)言切換只有兩種實(shí)現(xiàn)方式?,后端接口返回,缺點(diǎn),每次新增修改路由,后端都要在數(shù)據(jù)庫(kù)里面新增、修改兩種語(yǔ)言,較為麻煩,所以路由的語(yǔ)言切換就純前端進(jìn)行控制。

<template>
  <div v-if="!item.hidden">
    <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="generateTitle(onlyOneChild.meta.title)" />
        </el-menu-item>
      </app-link>
    </template>

    <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
      <template slot="title">
        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="generateTitle(item.meta.title)" />
      </template>
      <sidebar-item
        v-for="child in item.children"
        :key="child.path"
        :is-nest="true"
        :item="child"
        :base-path="resolvePath(child.path)"
        class="nest-menu"
      />
    </el-submenu>
  </div>
</template>

<script>
import path from 'path'
import { generateTitle } from '@/utils/i18n'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'

export default {
  name: 'SidebarItem',
  components: { Item, AppLink },
  mixins: [FixiOSBug],
  props: {
    // route object
    item: {
      type: Object,
      required: true
    },
    isNest: {
      type: Boolean,
      default: false
    },
    basePath: {
      type: String,
      default: ''
    }
  },
  data() {
    this.onlyOneChild = null
    return {}
  },
  methods: {
    hasOneShowingChild(children = [], parent) {
      const showingChildren = children.filter(item => {
        if (item.hidden) {
          return false
        } else {
          // Temp set(will be used if only has one showing child)
          this.onlyOneChild = item
          return true
        }
      })

      // When there is only one child router, the child router is displayed by default
      if (showingChildren.length === 1) {
        return true
      }

      // Show parent if there are no child router to display
      if (showingChildren.length === 0) {
        this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
        return true
      }

      return false
    },
    resolvePath(routePath) {
      if (isExternal(routePath)) {
        return routePath
      }
      if (isExternal(this.basePath)) {
        return this.basePath
      }
      return path.resolve(this.basePath, routePath)
    },
    generateTitle
  }
}
</script>

?需要注意的是,對(duì)于首頁(yè),是前端寫(xiě)的路由,其余的頁(yè)面路由都是后端接口返回的,所以在前端,針對(duì)首頁(yè),需要改的是router/index.js

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

九.菜單管理,和路由同理,都是后端接口返回,接口返回的語(yǔ)言切換,純前端處理

1.zh

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

2.en?

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

?

<script>
  computed: {
    ...mapState({
      language: state => state.app.language
    })
  },
  watch:{
    language(newVal, oldVal){
      this.getList()
    }
  },
methods:{
     getList() {
        this.loading = true;
        listMenu(this.queryParams).then(response => {
          this.menuList = this.handleTree(response.data, "menuId").map(item=>{
            const newItem= {
              ...item,
              menuName:this.$t(`route.${item.menuName}`)
            }
            if (newItem.children && newItem.children.length > 0) {
              newItem.children = this.translateChildren(newItem.children);
            }
            return newItem;
          });
          this.loading = false;
        });
      },
    translateChildren(children) {
      return children.map(item => {
        const newItem = {
          ...item,
          menuName: this.$t(`route.${item.menuName}`),
        };
        if (newItem.children && newItem.children.length > 0) {
          newItem.children = this.translateChildren(newItem.children);
        }
        return newItem;
      });
    },
}
</script>

?十.樣式處理,可能中文的長(zhǎng)度很短,英文長(zhǎng)度很長(zhǎng),樣式就會(huì)錯(cuò)亂,對(duì)于這種情況進(jìn)行處理

  <el-dialog :title="title" :visible.sync="open" width="850px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" :label-width="getLabelWidth()">
        <el-row>
          <el-col :span="12">
<!--            公告標(biāo)題-->
            <el-form-item :label="$t('notice.announcementtitle')" prop="noticeTitle" >
              <el-input v-model="form.noticeTitle" :placeholder="$t('notice.titleipt')" 
              style="width: 260px"/>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{$t('operation.confirm')}}</el-button>
        <el-button @click="cancel">{{$t('operation.cancel')}}</el-button>
      </div>
    </el-dialog>
getLabelWidth(){
      let labelWidth = '80px';
      if(this.language=='en'){
        labelWidth = '150px';
      }
      return labelWidth;
    },

十一.對(duì)于校驗(yàn)的地方,語(yǔ)言切換之后,并不會(huì)再次觸發(fā)校驗(yàn)的語(yǔ)言切換?,關(guān)于這個(gè)點(diǎn),我是進(jìn)行了監(jiān)聽(tīng),語(yǔ)言是否改變,如果語(yǔ)言改變了,我就再次觸發(fā)校驗(yàn),缺點(diǎn),每次切換語(yǔ)言就會(huì)出發(fā)校驗(yàn),并不是,我點(diǎn)擊了某個(gè)提交按鈕,進(jìn)行的校驗(yàn)觸發(fā),例如我上面寫(xiě)的登錄頁(yè)面上的校驗(yàn)

vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言,vue.js,javascript,前端

?以上就是整個(gè)實(shí)現(xiàn)過(guò)程啦,可能有點(diǎn)地方忘記寫(xiě)了,等想到了,再進(jìn)行完善文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-518912.html

到了這里,關(guān)于vue-i18n 實(shí)現(xiàn)國(guó)際化,支持切換不同語(yǔ)言的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3中,國(guó)際化插件vue-i18n使用記錄,配合VSCode自動(dòng)化翻譯插件i18n Ally

    Vue3中,國(guó)際化插件vue-i18n使用記錄,配合VSCode自動(dòng)化翻譯插件i18n Ally

    說(shuō)明文檔: vue-i18n 版本說(shuō)明: vue: 3.0.0+ vue-i18n: 9.x版 src 目錄下新建目錄 lang ,存放 i18n 的配置。 新建目錄名稱: lang (語(yǔ)言)、 locales (語(yǔ)系設(shè)定)、 i18n ,這些名稱都可被VSCode圖標(biāo)插件( vscode-icons )檢測(cè)到并美化。 lang 目錄下,新建 index.js 文件,引入 vue-i18n 。 語(yǔ)言的配置信

    2024年02月12日
    瀏覽(26)
  • vue-i18n國(guó)際化多語(yǔ)言與多套UI組件庫(kù)使用(Element Plus、Ant Design Vue、Naive UI)

    vue-i18n國(guó)際化多語(yǔ)言與多套UI組件庫(kù)使用(Element Plus、Ant Design Vue、Naive UI)

    demo源碼:Vue3 UI Lang 因調(diào)研需要,需在同一個(gè)項(xiàng)目中集成好幾種UI組件庫(kù)的多語(yǔ)言實(shí)現(xiàn),查看各種組件庫(kù)的表現(xiàn)情況,以便選定組件庫(kù)。 注意:這只在調(diào)研過(guò)程中會(huì)如此,實(shí)際開(kāi)發(fā)項(xiàng)目中極少存在一個(gè)項(xiàng)目中集成多個(gè)UI組件庫(kù)的情況。 本demo實(shí)際試驗(yàn)阿拉伯語(yǔ)、法語(yǔ)、葡萄牙語(yǔ)

    2024年02月08日
    瀏覽(51)
  • 用i18n 實(shí)現(xiàn)vue2+element UI的國(guó)際化多語(yǔ)言切換詳細(xì)步驟及代碼

    用i18n 實(shí)現(xiàn)vue2+element UI的國(guó)際化多語(yǔ)言切換詳細(xì)步驟及代碼

    這個(gè)地方要注意自己的vue版本和i1n8的匹配程度,如果是vue2點(diǎn)幾,記得安裝i18n的@8版本,不然會(huì)自動(dòng)安裝的最新版本,后面會(huì)報(bào)錯(cuò)哦,查詢了下資料,好像最新版本是適配的vue3。 在src下面新建i18n文件夾,然后在里面新建index.js,里面的內(nèi)容如下 新建i18n文件夾里面新建config文

    2024年02月14日
    瀏覽(32)
  • 微信小程序-切換語(yǔ)言(國(guó)際化i18n)的方法封裝

    微信小程序-切換語(yǔ)言(國(guó)際化i18n)的方法封裝

    最近做的一個(gè)小程序的項(xiàng)目, 涉及到了 多語(yǔ)言的切換 , 就想到了之前vue用的多語(yǔ)言插件i18n, 就嘗試著在微信開(kāi)放社區(qū)搜了一下, 沒(méi)有具體的實(shí)現(xiàn), 但是提供了大致的實(shí)現(xiàn)思路, 如下: 又結(jié)合了很多大佬的分享經(jīng)驗(yàn), 試著去封裝了一個(gè)微信的i18n方法 首先, 我們需要明確一下需要實(shí)

    2024年02月05日
    瀏覽(21)
  • SpringBoot 國(guó)際化(i18n) 支持中文鍵(KEY)的解決方法

    前言: 項(xiàng)目中要解決“中英文”切換的問(wèn)題,想法是輸入key例如“你好”,然后去國(guó)際化文件找對(duì)應(yīng)的中文key,然后進(jìn)行輸出,如果沒(méi)有定義這個(gè)key,則輸出“你好”。但是中文key在properties文件中會(huì)已unicode編碼輸出,使用中文key時(shí)獲取不到對(duì)應(yīng)的value。 解決方法: 重構(gòu)$.

    2024年02月16日
    瀏覽(30)
  • Vue - i18n 國(guó)際化的使用

    參考網(wǎng)址: 使用:?https://huaweicloud.csdn.net/638f133edacf622b8df8eb26.html?spm=1001.2101.3001.6650.1utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-1-125181861-blog-123845480.235%5Ev38%5Epc_relevant_anti_t3_basedepth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Ea

    2024年02月11日
    瀏覽(21)
  • SpringBoot+Vue前后端分離項(xiàng)目國(guó)際化支持

    SpringBoot+Vue前后端分離項(xiàng)目國(guó)際化支持

    i18n.js文件 language.en_US.js文件 language.zh_CN.js文件 messages_en_US.properties文件 messages_zh_CN.properties文件

    2024年02月04日
    瀏覽(25)
  • i18n(國(guó)際化)代碼簡(jiǎn)單實(shí)現(xiàn)

    i18n(國(guó)際化)代碼簡(jiǎn)單實(shí)現(xiàn)

    各個(gè)國(guó)家都有各個(gè)國(guó)家的語(yǔ)言,如果網(wǎng)站需要讓全世界的人使用,那就需要進(jìn)行國(guó)際化功能開(kāi)發(fā) 國(guó)際化我知道的一共有兩種,其中一種是不同國(guó)家不同網(wǎng)站,也就是說(shuō)頁(yè)面風(fēng)格都不一樣。另外一種是網(wǎng)站都是一樣的,只是里面的文字不同罷了。第一種沒(méi)啥好說(shuō)了,畢竟都是兩

    2024年02月07日
    瀏覽(23)
  • 如何在Vue3中配置國(guó)際化語(yǔ)言i18n

    1. 安裝 vue-i18n 2. 創(chuàng)建一個(gè)i8n的配置文件 如:i18nConfig.js 3. 新建語(yǔ)言文件 zh-CN.js 和 en-US.js zh-CN.js 文件 en-US.js 文件 CONFIG.js 文件 4. 在 main.js 里面全局配置 通過(guò)上面四步即可配置完畢 下面說(shuō)一下如何使用,分三種情況 在 .vue 組件中的 template 使用 在 .vue 組件中的 script 中使用 在

    2024年02月09日
    瀏覽(23)
  • 微信小程序配置實(shí)現(xiàn)中英文國(guó)際化語(yǔ)言切換

    微信小程序配置實(shí)現(xiàn)中英文國(guó)際化語(yǔ)言切換

    目錄 1,在根目錄新建文件夾和js文件 2. 在main.js中設(shè)置全局語(yǔ)言狀態(tài)(默認(rèn)設(shè)置為中文) 3. 頁(yè)面添加? 語(yǔ)言切換按鈕(登錄頁(yè)面) 4. 在需要顯示的頁(yè)面導(dǎo)入使用 根目錄新建一個(gè)locales.js文件, 通用的一些函數(shù)可以放在此文件該文件夾下?,如下圖所示 配置中英文字段,字段要一

    2024年02月12日
    瀏覽(95)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包