立即更改区域设置不会相应地刷新vue.js组件

时间:2018-11-21 08:50:23

标签: javascript vue.js momentjs

我有一个js类User,里面有一个矩对象:

import moment from 'moment'
class User {
    expirationDate = moment();
}

我想根据应用的语言环境显示此日期。我正在使用VueJS。为了方便访问Vue组件中的矩变量,我公开了矩变量:

Vue.prototype.$moment = moment;

在我的组件中,有一个按钮,允许用户更改其区域设置。

this.$moment.locale(newLocale); // newLocale can be en-us, zh-cn, ....

但是日期未翻译。 为了进一步讲解,我在同一个模块中做了以下创建的函数:

  created: function() {
    setInterval(() => {
      console.log(this.$moment.locale());
      console.log(this.user.expirationDate.format('ll'));
      console.log(this.$moment().format('ll'));
    }, 1000);
  }

这是结果

UserProfile.vue?ebc3:52 en
UserProfile.vue?ebc3:52 Nov 30, 2018
UserProfile.vue?ebc3:53 Nov 21, 2018
UserProfile.vue?ebc3:51 zh-cn
UserProfile.vue?ebc3:52 Nov 30, 2018
UserProfile.vue?ebc3:53 2018年11月21日

所以我不明白为什么我的用户提示格式无法正常工作。 我担心$ moment和我的user.js中使用的那一刻之间的矩变量实例不同。所以我最终尝试了这个:

console.log(this.$moment(this.user.expirationDate).format('ll'));

但结果是相同的:完全不翻译! 我还将此添加到了我的User类:

import moment from 'moment'
class User {
    expirationDate = moment();
    constructor(data) {
        setInterval(()=>{console.log('from user.js > ' + moment.locale())}, 1000)
    }
}

,并通知语言环境正确。因此,这似乎不是一个可变的问题...

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

类似的问题:

我的应用程序有一个顶部栏,其中包含用于更改语言环境的选择输入。 呈现组件时,如果我更新语言环境,则不会重新呈现该组件,因此日期格式仍然相同。...

什么可以帮助我找到干净的解决方案

阅读this article

实践中的解决方案

编辑您的AppComponent的html模板,以添加此属性:key:"language",例如:

<div :key="language">
    <router-view></router-view>
</div>

然后编辑您的AppComponent类:

data: {
    selectedLanguage: 'fr'
},
computed: {
    language: function () {
      return this.selectedLanguage;
    }
}

当更改selectedLanguage值时,组件的key属性值将更改并触发AppComponent重新渲染,并且其子对象也将重新渲染。

要确保在全局重新渲染之前已更新了力矩配置,请确保在更新this.$moment.locale(newLocale)之前先调用selectedLanguage方法。

PS: 我已经从应用程序中翻译了使用Vue Property DecoratorVuex的代码,请告诉我是否遗漏了一些东西。

答案 1 :(得分:0)

我只想与可能需要它的人分享我的解决方案。 我正在用vuex为i18n存储lang

state:{locale:'en'}, //en by default                                                             
getters:{locale: (state) => state.locale,},                                   
mutations: { SET_LOCALE: (state, payload) => {locale = payload|| state.locale;}}                    
actions: {
SetLocale: async (context, payload) => {
  context.commit('SET_LOCALE', payload);
  await setLocale(payload.locale);
},

}

然后将基本下拉菜单放到导航栏或要更改语言的位置,并添加方法以推送新语言进行存储

 methods: {
    async setLocale(locale) {
        await this.$store.dispatch('SetLocale', {
            locale
        });
    },
},

比在您的应用程序中。vue应用上面的“关键”解决方案,并观察商店数据的变化

<v-main :key="locale">
<transition name="fade-transform" mode="out-in">
    <keep-alive>
        <router-view />
    </keep-alive>
</transition>                                                                      

并添加观察者和跟踪方法

....... 
 computed: {
    ...mapGetters(["errors", "locale"])
},
watch: {
    locale: {
        immediate: true,
        handler(newVal, oldVal) {
            this.setLang(newVal)
        },
    },
},
methods: {
    setLang(lang) {
        this.$moment.locale(lang);
        console.log('dil değişti', lang)
    }
},                                                                           

每次更改i18n lang都会强制导入新的lang,并使用正确的lang刷新主组件。