Vue-i18n多语言搭配vuex的混合使用-案例

Posted JackieDYH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue-i18n多语言搭配vuex的混合使用-案例相关的知识,希望对你有一定的参考价值。

安装

// 安装 vue-i18n
npm install --save vue-i18n
// 安装 js-cookie
npm install --save js-cookie
// 安装 vuex
npm install --save vuex

 i18n 封装

将i18n引入与注册实例封装在了./langs/index.js中

import Vue from 'vue';
import VueI18n from 'vue-i18n';
import Cookies from 'js-cookie';
import enLocale from './en';
import zhLocale from './zh';

Vue.use(VueI18n);

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

  // if has not choose language
  const language = (navigator.language || navigator.browserLanguage).toLowerCase()
  const locales = Object.keys(messages)
  for (const locale of locales) {
    if (language.indexOf(locale) > -1) {
      return locale
    }
  }
  return 'en'
}
const i18n = new VueI18n({
  locale: getLanguage(),
  // set locale messages
  messages
})

export default i18n

脚本配置

//zh.js
export default {
  settings: {
    title: '多语言',
    theme: '内容内容内容',
  }
}


//en.js
export default {
  settings: {
    title: 'Multilingual',
    theme: 'content',
  }
}

vuex

./store/index.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

import state from './state';
import mutations from './mutation';
import actions from './action';
import getters from './getter';

// 这种方式很好的将modules中的所有文件全部导出,这样以后修改modules不用再在此处进行添加导出
const modulesFiles = require.context('./modules', true, /\\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  const moduleName = modulePath.replace(/^\\.\\/(.*)\\.\\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {});

// 实例化Vuex
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules
});

getters

export default {
    // 监听 vuex 中state下language的改变
    // 外部通过 this.$store.getters.language 调用
    language: state => state.app.language,
}

app.js 

./store/modules/app.js
单独建立一个app.js,方便以后如果需要扩展其他的全局状态,可以封装在其他独立的js中

// 获取当前国际化状态封装在了上面的./langs/index.js中,相当于是初始化国际化
import { getLanguage } from '@/langs/index';
import Cookies from 'js-cookie';
// 数据,外部可以通过 this.$store.state.language 调用
const state = {
  language: getLanguage()
}
// 外部可以通过提交mutation来修改state中的值
// this.$store.commit("SET_LANGUAGE")
const mutations = {
  SET_LANGUAGE: (state, language) => {
    // 修改state并将其保存在Cookies中,这样用户下次打开仍然是上次选择的国际化状态
    state.language = language
    Cookies.set('language', language)
  },
}
// 官方推荐我们去提交一个actions,在actions中提交mutation再去修改state
// this.$store.dispatch("setLanguage")
const actions = {
  setLanguage({ commit }, language) {
    commit('SET_LANGUAGE', language)
  },
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}

main.js

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
// // 导入封装的i18n配置
import i18n from './langs/index';


Vue.config.productionTip = false;

new Vue({
  router,
  store,
  i18n,
  render: (h) => h(App),
}).$mount("#app");

使用

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
      <button :disabled="language === 'zh'" @click="handleSetLanguage('zh')">中文</button>
      <button :disabled="language === 'en'" @click="handleSetLanguage('en')">English</button>
    
    <!-- html中使用 -->
    dyh-{{ $t('settings.title') }}-{{$t('settings.title')}}--{{lang}}
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  components: {
    HelloWorld,
  },
  data(){
    return{
      lang : this.$t('settings.title'),//js中使用
    }
  },
  computed: {
    // 通过computed获取vuex中的language状态,这样其他地方修改后这边可以监测到,并同步修改DOM中的值
    language() {
      return this.$store.getters.language;
    },
  },
  methods: {
    handleSetLanguage(lang) {
      // 设置i18n,以便后面通过$t('settings.title')使用
      this.$i18n.locale = lang;
      // 向vuex提交修改后的国际化,以便后面获取
      this.$store.dispatch("app/setLanguage", lang);
    },
  },
};
</script>

注意:i18n中在data中使用,切换语言是不会改变的。

解决方式:

        1、可以使用改变语言刷新一下页面的方式让data中的值重新加载

        2、在vue中使用计算属性computed,就可以解决

以上是关于Vue-i18n多语言搭配vuex的混合使用-案例的主要内容,如果未能解决你的问题,请参考以下文章

vue项目支持多语言(vue-i18n)

vue项目支持多语言(vue-i18n)

vue-i18n 多语言开发

vue-i18n 多语言开发

vue 多语言 vue-i18n 按需加载,异步调用

VUE+webpack+npm项目中的多语言vue-i18n@8.x