Vue+i18n多语言动态设置(保姆级案例教程)

效果 😉:

多语言

一、前言 ☀️

最近做项目要求前端显示i18n多语言国际化,做完后,发现网上很多教程都不够详细,也不全,吃了不少憋,对我这种新人极不友好,现在总结做了个简单多语言demo,希望大佬们指点一下!!!

总结遇到问题,稍安勿躁,关键把思路弄明白,剩下的都是小Ks。

二、技术介绍 ✏️

i18n:Vue.js 的国际化插件。它可以轻松地将一些本地化功能集成到你的 Vue.js 应用程序中

i18n的官网地址安装 | Vue I18n (kazupon.github.io)

三、本案例是vant+vue2+localStorage,还搭配了moment.js工具类 ❤️❤️❤️

官网的例子:开始 | Vue I18n (kazupon.github.io)

而本案例是基于官网例子加以延伸,在messages中不仅可以自定义项目业务所需的文字语言包,还可以把vantUI组件内置的文字也进行多语言化,合并两个的语言包,并在vue组件动态修改,切换整体的语言包,从而实现多语言。

1、安装插件 ☕️☕️
npm install vue-i18n --save
npm i vant --save
npm i moment --save
2、创建i18n文件index.js 🍺🍺

在src目录中创建i18n文件夹,在文件夹中创建index.js文件,用于全局配置多语言文件

(对Vant UI库 、业务自定义语言包 、moment时间处理类 进行了多语言的处理)

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { Locale } from 'vant'
// 引入组件的语言包
import zhCN from 'vant/es/locale/lang/zh-CN'
import zhHK from 'vant/es/locale/lang/zh-HK'
import enUS from 'vant/es/locale/lang/en-US'
// 引入业务自定义的语言包
const localCN = require('./locale/zh') // 简体
const localHK = require('./locale/hk') // 繁體
const localUS = require('./locale/en') // English
// 在这里引入moment了,所以不在main.js引入了
import Moment from 'moment'
Vue.prototype.$moment = Moment
Vue.use(VueI18n);

// 语言包的类型合并
const messages = {
  'zh_CN': { ...zhCN, ...localCN },
  'zh_HK': { ...zhHK, ...localHK },
  'en_US': { ...enUS, ...localUS }
}

// localStorage获取当前语言类型(初次本地不存在'lang'字段存储,默认设置为'zh_CN')
const lang = localStorage.getItem('lang') || 'zh_CN'
console.log('初始语言类型', lang);

// 初次加载的语言默认设置
Locale.use(lang, messages[lang])
// 时间类moment语言默认设置
Moment.locale(lang)

export default new VueI18n({
  locale: lang, // set locale 
  messages: messages // set locale messages
});
3、创建业务自定义语言包 🍔🍔🍔

在i18n文件夹中创建locale文件夹,在里面设置多语言包,en.js / hk.js / cn.js

en.js

module.exports = {
    login: {
        'username': 'Please enter the user name',
        'password': 'Please enter your password',
        'Username': 'Username',
        'Password': 'Password'
    },
    form: {
        'submit': 'Submit'
    }
}

hk.js

module.exports = {
    login: {
        'username': '請輸入用戶名',
        'password': '請輸入密碼',
        'Username': '用戶名',
        'Password': '密碼'
    },
    form: {
        'submit': '提交'
    }
}

zh.js

module.exports = {
  login: {
    'username': '请输入用户名',
    'password': '请输入密码',
    'Username': '用户名',
    'Password': '密码'
  },
  form: {
    'submit': '提交'
  }
}

文件创建如图所示 :

在这里插入图片描述

4、main.js引入i18n配置文件 🍟🍟
// 【i18n多语言】
import i18n from './i18n/index'
new Vue({
  i18n,
  render: h => h(App),
}).$mount('#app')
5、Vue组件中动态切换语言 🍕🍕🍕🍕

<template>
  <div class="main">
    <div class="main-header">
      <div class="header-logo">
        <img class="logo-img" src="@/assets/img/userimg2.png" alt="#">
      </div>
    </div>
    <div class="main-form">
      <van-form @submit="onSubmit" class="login-form">
        <van-field class="login-username" v-model="username" name="用户名" :label="$t('login.Username')" :placeholder="$t('login.username')"
        :rules="[{ required: true, message: $t('login.username') }]" />
        <van-field class="login-password" v-model="password" type="password" name="密码" :label="$t('login.Password')"
        :placeholder="$t('login.password')" :rules=" [{ required: true, message: $t('login.password') }]" />
        <van-radio-group class="login-radio" v-model="lang" direction="horizontal"  @change="changelang">
          <van-radio name="zh_CN">中文|简体</van-radio>
          <van-radio name="zh_HK">中文|繁体</van-radio>
          <van-radio name="en_US">English</van-radio>
        </van-radio-group>
        <div style="margin: 10px;">
          <van-button round block type="info" native-type="submit">{{$t('form.submit')}}</van-button>
        </div>
      </van-form>
    </div>


      <div class="time">
        <van-field style="flex:1;border-right: 1px solid #a3a3a3;" readonly v-model="currentDate" label="时间:" label-width="45"></van-field>
        <van-button style="width: 90px" @click="() => (isShowTime = !isShowTime)" :disabled="isShowTime">选择时间</van-button>
      </div>
      <van-datetime-picker 
        v-if="isShowTime"
        type="datetime" 
        title="选择年月日" 
        @confirm="(value)=>ok_Time(value)" 
        @cancel="() => (isShowTime = !isShowTime)" 
        :min-date="minDate" 
        :max-date="maxDate" 
      />
  </div>
</template>

<script>
import { Locale } from 'vant';
import Moment from 'moment';
import language from '../../i18n/index'
export default {
  name: 'Login',
  data() {
    return {
      username: '',
      password: '',
      id: '',
      lang: '',
      minDate: new Date(2022, 10, 1),
      maxDate: new Date(2025, 10, 1),
      nowDate: new Date(),
      currentDate:this.$moment().calendar(),
      isShowTime:false
    }
  },
  created() {
    this.lang = localStorage.getItem('lang') || 'zh_CN'
  },
  watch: {
    lang(newValue, old) {
      if (newValue != old) {
        Moment.locale(this.lang)
        console.log('监听了',this.nowDate);
        // 注;moment修改语言后需重新渲染(通过双向绑定原理,重新渲染)。
        // 但是在这样写就不方便了,因为一个组件中可能会多处使用moment.js,这样都需要重新赋值渲染,
        this.currentDate = this.$moment(this.nowDate).calendar()
      }
    }
  },
  methods: {
    changelang() {
      const messages = language._vm.messages
      this.$i18n.locale = this.lang
      Locale.use(this.lang, messages[this.lang])
      this.$message.success('切换语言成功')
      // localStorage存储当前语言类型
      localStorage.setItem('lang', this.lang)
    },
    ok_Time(value){
      this.nowDate = value
      this.currentDate = this.$moment(value).calendar()
      this.isShowTime = !this.isShowTime
    },
    onSubmit(values) {
      console.log('submit', values);
    }
  }
};
</script>

<style lang="less" scoped>
.main {
  width: 100%;
  height: 100vh;
  background: url('@/assets/img/loginBg.jpg') no-repeat;
  // background-size: (100%,100%);
  background-size: cover;
  background-position: center 0;
  background-attachment: fixed;
  .main-header{
    height: 30%;
    position: relative;
    .header-logo{
      position: relative;
      top: 65%;
      left:50%;
      transform: translate(-50%,-50%);
      height: 120px;
      width: 120px; 
      // border: 1px solid white;
      box-shadow: 1px 1px 2px white;
      .logo-img{
        width: 100%;
        height: 100%;
      } 
    }
  }
  .main-form{
    margin:20px;
    .login-form{
      border-radius: 10px;
      border: 1px solid rgb(189 176 255);
      padding: 10px;
      // background: rgb(189 176 255 / 50%);
      background: rgba(255, 255, 255, 0.5);
      .login-username{
        margin-bottom: 10px;
      }
      .login-password{
        margin-bottom: 10px;
      }
      .login-radio{
        margin-bottom: 20px;
      }
    }
  }
  .time{
    margin: 20px;
    display: flex;
  }
}
</style>

❤️❤️❤️在这里插入图片描述❤️❤️❤️

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值