• vue-i18n实现不刷新页面切换页面语言和element-ui的语言


    开发环境

    系统环境 windows 10
    vue版本 2.6.11
    λ node -v v12.19.0 λ npm -v 6.14.8 λ vue -V @vue/cli 4.5.7

    项目目录结构

    安装必要的包

    vue-i18n
    element-ui
    vue-router
    vuex
    

      

    新建i18n文件的翻译语言包

    // src/store/i18n/lang/en.js
    // explore 的方式需要加花括号导入
    import { enHello } from './modules/HelloWorld'
    
    export default {
        ...enHello,
        login: {
            username: 'username'
        },
        chooseDate: 'Choose Date:',
        exchangeLanguage: 'Exchange Language',
        home: 'Home',
        about: 'about'
    }
    

     

    // src/store/i18n/lang/zh.js
    
    import {zhHello} from './modules/HelloWorld'
    
    export default {
        ...zhHello,
        login: {
            username: '用户名'
        },
        chooseDate: '选择日期:',
        exchangeLanguage: '切换语言',
        home: '首页',
        about: '关于'
    
    }
    

      

    // src/store/i18n/lang/modules/HelloWorld.js
    
    export const  enHello = {
      date: 'Date',
      title: 'Sport Brands',
      nike: 'Nike',
      adi: 'Adidas',
      nb: 'New Balance',
      ln: 'LI Ning'
    };
    
    export const zhHello = {
      date: '日期',
      title: '运动品牌',
      nike: '耐克',
      adi: '阿迪达斯',
      nb: '新百伦',
      ln: '李宁'
    };
    

      

    // src/store/i18n/index.js
    
    // 引入必要的库
    import Vue from 'vue'
    import VueI18n from 'vue-i18n'
    // 引入element ui国际化文件
    import elen from 'element-ui/lib/locale/lang/en'
    import elcn from 'element-ui/lib/locale/lang/zh-CN'
    import ElementLocale from 'element-ui/lib/locale'
    
    // 引入工具函数
    import { getStorage, getBrowserLang } from '@/util'
    
    // 引入项目中需要用到的中英文文案配置js
    import enLocale from './lang/en'
    import cnLocale from './lang/zh'
    
    // 使用vue-i18n库
    Vue.use(VueI18n);
    
    // 获取当前语言(初始化时localStorage里没有存语言,默认为浏览器当前的语言)
    const lang = getStorage('lang') || getBrowserLang();
    
    // 组合element ui 和 项目自身的文案文件
    const messages = {
        'en': {
            ...elen,
            ...enLocale
        },
        'zh': {
            ...elcn,
            ...cnLocale
        }
    };
    
    // 创建vueI18n实例并输出,在main.js中调用
    const i18n = new VueI18n({
        locale: lang,
        messages,
        silentFallbackWarn: true,  // 设置为true后,在组件内使用时在浏览器不会报警告
    });
    
    ElementLocale.i18n((key, value) => i18n.t(key, value));
    export default i18n
    

      

    新建工具方法文件

    // src/util.js
    
    // 设置localStorage
    export const setStorage = function(key, obj) {
        let json = JSON.stringify(obj);
        window.localStorage.setItem(key, json)
    };
    
    // 获取localStorage
    export const getStorage = function(key) {
      const str = window.localStorage.getItem(key);
      if (!str) {
          return null
        }
        return JSON.parse(str)
    };
    
    // 移除localStorage
    export const removeStorage = function(key) {
        window.localStorage.removeItem(key)
    };
    
    // 获取浏览器默认语言
    export const getBrowserLang = function() {
      let browserLang = navigator.language ? navigator.language: navigator.browserLanguage;
      let defaultBrowserLang = '';
        if (browserLang.toLowerCase() === 'cn' || browserLang.toLowerCase() === 'zh' || browserLang.toLowerCase() === 'zh-cn') {
            defaultBrowserLang = 'zh'
        } else {
            defaultBrowserLang = 'en'
        }
        return defaultBrowserLang
    };
    

      

    配置mian.js

    //  src/main.js
    
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import i18n from "./store/i18n";
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI);
    
    
    Vue.config.productionTip = false;
    
    new Vue({
      router,
      store,
      i18n,
      render: h => h(App)
    }).$mount('#app');
    

      

     

     使用vuex来变更语言状态

    // src/store/index.js
    
    import {
        getStorage,
        setStorage,
        getBrowserLang
    }
    from '@/util'
    
    export default {
      state: {
          language: getStorage('lang') || getBrowserLang(), // 项目初始化时,默认为浏览器的语言
      },
      getters: {
          language: state => state.language,
        },
      mutations: {
          setLanguage: (state, language) => {
              state.language = language;
              setStorage('lang', language);
          }
      }
    }
    

      

    //  src/store/modules/language.js
    
    import {
        getStorage,
        setStorage,
        getBrowserLang
    }
    from '@/util'
    
    export default {
      state: {
          language: getStorage('lang') || getBrowserLang(), // 项目初始化时,默认为浏览器的语言
      },
      getters: {
          language: state => state.language,
        },
      mutations: {
          setLanguage: (state, language) => {
              state.language = language;
              setStorage('lang', language);
          }
      }
    }
    

      

      

    修改页面内容

    // src/App.vue
    
    <template>
      <div id="app">
        <router-view/>
      </div>
    </template>
    
    <style lang="scss">
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    </style>
    

      

    注意:data中使用i18n时切换语言不会更新,所以还是得刷新路由才能根本解决问题。

    // src/views/Home.vue
    
    <template>
      <div class="home">
          <HelloWorld msg="Welcome to Your Vue.js App"/>
          <el-main>
            <el-table :data="tableData" style=" 100%">
              <el-table-column :label="$t('date')" >
                  <span class="demonstration">{{ $t("chooseDate") }}</span>
                  <el-date-picker v-model="value1" type="date" placeholder=""></el-date-picker>
              </el-table-column>
              <el-table-column prop="name" :label="$t('title')"></el-table-column>
            </el-table>
          </el-main>
      </div>
    </template>
    
    <script>
    // @ is an alias to /src
    import HelloWorld from '@/components/HelloWorld.vue'
    
    export default {
      name: 'Home',
      components: {
        HelloWorld
      },
        data () {
          return {
            value1: '',
            tableData: [{
                date: '2016-05-02',
                name: this.$t('nike'),
              }, {
                date: '2016-05-04',
                name: this.$t('adi'),
              }, {
                date: '2016-05-01',
                name: this.$t('nb'),
              }, {
                date: '2016-05-03',
                name: this.$t('ln'),
              }]
          }
        }
    }
    </script>
    
    <style>
      .el-main {
        background-color: #E9EEF3;
        color: #333;
        text-align: center;
      }
    </style>
    

      

    注意:在组件中使用i18n配置会导致全局的状态不能变更和element-ui语言不能切换。

    // src/components/HelloWorld.vue
    
    
    <template>
      <div class="hello">
        <el-container>
          <el-header>
            <el-row>
              <el-col :span="5"><router-link to="/">{{ $t("home") }}</router-link></el-col>
              <el-col :span="5"><router-link to="/about">{{ $t("about") }}</router-link></el-col>
              <el-col :span="5">{{ $t("exchangeLanguage") }}</el-col>
              <el-col :span="5">
                <el-dropdown @command="handleSetLang" trigger="click">
                  <div class="lang-active">
                    <div v-for="(lang, i) in langs" :key="`LangActive${i}`" v-show="lang.key === activeLang">{{ lang.value }}
                      <i class="el-icon-arrow-down el-icon--right"></i></div>
                  </div>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item v-for="(lang, i) in langs" :key="`Lang${i}`" :command="lang.key">
                      <span class="text">{{ lang.value }}</span></el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
              </el-col>
              <el-col :span="4">{{$t('login.username')}}</el-col>
            </el-row>
    
          </el-header>
    <!--      <el-main>-->
    <!--        <div class="block">-->
    <!--          <span class="demonstration">{{ $t("chooseDate") }}</span>-->
    <!--          <el-date-picker v-model="value1" type="date" placeholder="">-->
    <!--          </el-date-picker>-->
    <!--        </div>-->
    <!--      </el-main>-->
        </el-container>
    
      </div>
    </template>
    
    <script>
    import {
        mapGetters,
        mapMutations
      } from 'vuex';
    export default {
      name: 'HelloWorld',
      // i18n:{
      //     messages:{
      //       en: {
      //         title: 'Sport Brands',
      //         nike: 'Nike',
      //         adi: 'Adidas',
      //         nb: 'New Banlance',
      //         ln: 'LI Ning'
      //       },
      //       zh: {
      //         title: '运动品牌',
      //          nike: '耐克',
      //           adi: '阿迪达斯',
      //           nb: '新百伦',
      //           ln: '李宁'
      //       },
      //     }
      // },
      data () {
        return {
          value1: '',
          langs: [{
              key: 'zh',
              value: '中文'
            },
            {
              key: 'en',
              value: 'EngLish'
            },
            ],
        }
      },
     computed: {
          ...mapGetters({
            activeLang: 'language',
          })
        },
     methods: {
          ...mapMutations(['setLanguage']),
          handleSetLang(lang) {
            // 设置i18n.locale 组件库会按照上面的配置使用对应的文案文件
            this.$i18n.locale = lang
            // 提交mutations
            this.setLanguage(lang)
          }
        }
    
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
      .el-header {
        background-color: #B3C0D1;
        color: #333;
        text-align: center;
        line-height: 60px;
      }
    
      body > .el-container {
        margin-bottom: 40px;
      }
      body {
        margin: 0;
        bottom: 0;
      }
      a {
        font-weight: bold;
        color: #2c3e50;
        /*text-decoration: none;*/
      }
      .router-link-exact-active {
          color: #42b983;
      }
    </style>
    

      

     最终效果对比

     你的start是我前进的动力,谢谢!本文GitHub项目地址

    刷新页面版链接

    本文参考链接1

    本文参考链接2

  • 相关阅读:
    限制泛型可用类型,类型通配符声明,泛型方法
    泛型简介,泛型类及使用
    异常概念和处理机制,try-catch-finally,throw和throws,自定义异常
    随机验证码
    常用类--Date日期类,SimpleDateFormat日期格式类,Calendar日历类,Math数学工具类,Random随机数类
    String、StringBuffer和StringBuilder,定义一个自己的StringBuilder的类
    自动装箱和拆箱,枚举类型
    使用内部类开发一个存放数据的容器
    手推期望、方差
    ML 徒手系列 最大似然估计
  • 原文地址:https://www.cnblogs.com/chen55555/p/13848174.html
Copyright © 2020-2023  润新知