Vue+i18n实现语言切换

开发背景

新项目需求前端进行国际化语言切换功能,我们前端用的是vue,组件使用了elementUI,这里通过i18n进行语言切换功能开发

环境准备

语言版本
Vue2.6.10
i18n^8.21.0

vue-i18n安装

npm install vue-i18n --save

配置

编写i18n组件

import Vue from 'vue'
import VueI18n from 'vue-i18n';
import locale from 'element-ui/lib/locale' // element-ui的语言环境
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 './components/Lang/en' //本地英文配置
import zhLocale from './components/Lang/cn' //本地中文配置
import Cookies from 'js-cookie'

Vue.use(VueI18n)

export default new VueI18n({
    locale:Cookies.get('language') || 'cn',   //从cookie里获取用户中英文选择,没有则默认中文
    messages:{
        'en': {
            ...enLocale,
            ...elementEnLocale  //引入elementUI的英文配置
        },
        'cn': {
            ...zhLocale,
            ...elementZhLocale  //引入elementUi的中文配置
        }
    }
})

locale.i18n((key, value) => i18n.t(key, value))

在main.js中引入i18n组件

Vue.use(Element, {
  size: Cookies.get('size') || 'medium', // set element-ui default size
  languate: Cookies.get('language') || 'cn',
  i18n: (key,value) => i18n.t(key, value)
})

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})

中英文js配置

cn.js

module.exports = {
    "language":{
        "cn":"中文",
        "en":"English",
    },
    "title":"仓储管理系统",
    "permission":{
        "button":{
            "login":"登录",
            "logout":"退出登录",
            "language":"语种"
        },
        "column":{
            "username":"账户",
            "password":"密码",
            "captcha":"验证码",
            "rememberMe":"记住密码"
        },
        "tips":{
            "loading":"登陆中。。。"
        },
        "rule":{
            "required":{
                "username":"用户名不能为空",
                "password":"密码不能为空",
                "captcha":"验证码不能为空"
            }
        }
    }
}

en.js

module.exports = {
    "language":{
        "cn":"中文",
        "en":"English",
    },
    "title": "WMS",
    "permission":{
        "button":{
            "login":"Log in",
            "logout":"Log out",
            "language":"Language"
        },
        "column":{
            "username":"Username",
            "password":"Password",
            "captcha":"Captcha",
            "rememberMe":"Remember me"
        },
        "tips":{
            "loading":"Loading..."
        },
        "rule":{
            "required":{
                "username":"Username can\"t be null",
                "password":"Password can\"t be null",
                "captcha":"Captcha can\"t be null"
            }
        }
    }
}

开发

template代码

在template使用{{$t("…")}}的格式

<template>
  <div class="login">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
      <h3 class="title">{{$t('title')}}
        <el-tooltip :content="$t('permission.button.language')" effect="dark" placement="bottom">
          <language-select id="language-select" class="right-menu-item hover-effect" />
        </el-tooltip>
      </h3>
      <el-form-item prop="username">
        <el-input v-model="loginForm.username" type="text" auto-complete="off" :placeholder="$t('permission.column.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('permission.column.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('permission.column.captcha')"
          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" />
        </div>
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">{{$t('permission.column.rememberMe')}}</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('permission.button.login')}}</span>
          <span v-else>{{$t('permission.tips.loading')}}</span>
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

script代码

在script中使用this.$t("…")的格式

<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
import LanguageSelect from '@/components/LanguageSelect'

export default {
  name: "Login",
  components:{
    LanguageSelect,
  },
  data() {
    return {
      codeUrl: "",
      cookiePassword: "",
      loginForm: {
        username: "admin",
        password: "admin123",
        rememberMe: false,
        code: "",
        uuid: ""
      },
      loginRules: {
        username: [
          { required: true, trigger: "blur", message: this.$t('permission.rule.required.username') }
        ],
        password: [
          { required: true, trigger: "blur", message: this.$t('permission.rule.required.password') }
        ],
        code: [{ required: true, trigger: "change", message: this.$t('permission.rule.required.captcha') }]
      },
      loading: false,
      redirect: undefined
    };
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect;
      },
      immediate: true
    }
  },
  created() {
    this.getCode();
    this.getCookie();
  },
  methods: {
    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>

测试

中文效果

在这里插入图片描述

英文效果

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值