Глобальное использование MomentJS в VueJS 3

#javascript #vue.js #momentjs #vuejs3

#javascript #vue.js #momentjs #vuex #vuejs3

Вопрос:

В VueJS 2 я мог бы использовать MomentJS глобально следующим образом:

в main.js :

 import moment from 'moment';
moment.locale('fr');
Object.defineProperty(Vue.prototype, '$moment', { value: moment });
 

в любом компоненте:

 {{ item.date_creation?$moment(item.date_creation).format('l'):'No date'}}
 

В VueJS 3 я попытался сделать следующее в main.js:

 import { createApp } from 'vue';
import moment from 'moment';
import App from './App.vue';
import './registerServiceWorker';
import router from './router';
import store from './store';

moment.locale('fr');

createApp(App).use(moment).use(store).use(router)
  .mount('#app');
 

Но на самом деле я не могу использовать «moment» ни в одном из моих компонентов, я должен импортировать «moment» в каждый из них.
Разве нет лучшего решения? Я прочитал много документации и руководств, я не увидел ничего хорошего…
Заранее спасибо.

Редактировать: вот как я использую $moment в своем компоненте:

 <template>
  <div class="xx" :key="'title-' myReactiveVariable.title">
    <h1>{{ myReactiveVariable.title }}</h1>
    <div class="yy">
      {{ myReactiveVariable.content }}
    </div>
    <footer>
      Sent on
      {{ myReactiveVariable.date }}
      by {{ myReactiveVariable.author }}
      <who-is-it :idSent="id" :key="'ID-' id">
      </who-is-it>
    </footer>
  </div>
</template>

<script>
// @ is an alias to /src
import WhoIsIt from '@/components/WhoIsIt.vue';

import {
  defineComponent, reactive, onMounted, watch, ref,
} from 'vue';

import axios from 'axios';

import { useRoute } from 'vue-router';

export default defineComponent({
  name: 'XXX',
  components: {
    WhoIsIt,
  },
  setup() {
    const route = useRoute();

    const myReactiveVariable = reactive({
      title: '',
      content: '',
      date: '',
    });

    const id = ref('');

    async function fetchArticle(id) {
      console.log(`A: ${process.env.VUE_APP_API_URL} - ${id}`);
      const res = await axios.get(`${process.env.VUE_APP_API_URL}/whoarewe/${id}`);
      id.value = res.data.author;
      myReactiveVariable.titre = res.data.title;
      myReactiveVariable.content = res.data.content;
      myReactiveVariable.date = this.$moment(res.data.date).format('l');
    }

    watch(() => route.params.id, () => {
      fetchArticle(route.params.id);
    });

    onMounted(async () => {
      fetchArticle(route.params.id);
    });

    return {
      myReactiveVariable,
      id,
    };
  },
});
</script>
 

Ответ №1:

Добавьте момент в глобальные свойства конфигурации app.config.globalProperties.$moment=moment :

 import { createApp } from 'vue';
import moment from 'moment';
import App from './App.vue';
import './registerServiceWorker';
import router from './router';
import store from './store';

moment.locale('fr');

let app=createApp(App);

app.config.globalProperties.$moment=moment;

app.use(store).use(router)
  .mount('#app');
 

затем используйте this.$moment в любом дочернем компоненте с option api, с композицией, которую вы должны использовать getCurrentInstance :

 import { getCurrentInstance } from 'vue'

setup(){
  const internalInstance = getCurrentInstance()
  ...
  myReactiveVariable.date = internalInstance.appContext.config.globalProperties.$moment(res.data.date).format('l');

}
 

Вы не могли этого сделать app.use(moment) , поскольку moment не является плагином Vue.

Комментарии:

1. Спасибо за ваш ответ. К сожалению, у меня есть Uncaught (in promise) TypeError: this is undefined , когда я ставлю для примера myReactiveVariable.date = this.$moment(res.data.date).format('l');

2. где вы, пожалуйста, поделились всем сценарием