Добрый день! Помогите, знающие люди, разобраться в следующей проблеме:
Разрабатываю домашнего питомца на Vue.js фронте и Symfony 4 бэк. Перед инициализацией приложения необходимо выполнить запрос к серверу, чтобы получить роуты для api и некоторые другие "первичные" данные - авторизован ли пользователь, если да - информация о нем. Проблема в том, что запрос асинхронный и данные прилетают в приложение немного позже, чем приложение отрендерится. Запрос на получение роутов api произвожу в хуке (пробовал в created, beforeCreated, mounted) App.vue, пробовал сделать его в главном файле js, в котором, собственно, создается экземпляр Vue, и в успешном колбеке этого первичного запроса создавать new Vue, но там вылезла проблема с записью полученных по api первичных данных в $store.
Детальное описание с файлами:
Файл, где подключаются модули, роутер, стора, создается экземпляр Vue.
app.jsimport Vue from 'vue';
import axios from 'axios';
import vueAxios from 'vue-axios';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './vue/App';
import LoginForm from './vue/element/LoginForm';
import ItemsList from './vue/element/ItemsList';
require('../css/app.styl');
Vue.component('App', App);
Vue.use(VueRouter);
Vue.use(vueAxios, axios);
Vue.use(Vuex);
Vue.use(ElementUI);
Vue.use(LoginForm);
const router = new VueRouter({
mode: 'history',
routes: [
{path: '/', component: LoginForm, name: 'LoginForm'},
{path: '/list/', component: ItemsList, name: 'ItemsList'},
],
});
const store = new Vuex.Store({
state: {
isAuth: false,
user: {},
itemsList: {},
filterOptions: {},
path: router.currentRoute.path,
api: {},
pagination: {},
},
mutations: {
set(state, {type, value}) {
state[type] = value;
},
go(state, {path}) {
router.push(path);
state.path = path;
},
multiSet(state, {value}) {
for (let key in value) {
state[key] = value[key];
}
}
},
getters: {
getPath: state => {
state.path = router.currentRoute.path;
return state.path;
},
},
});
const vm = new Vue({
el: '#app',
router,
store
});
Главный файл приложения, в его хуках я пытался загрузить данные в стору
App.vue<template>
<div class="app">
<header-navigator :defaultIndexProp="defaultIndexProp"></header-navigator>
<transition name="el-fade-in" mode="out-in">
<router-view @goToList="toList" v-if="api"></router-view>
</transition>
</div>
</template>
<script>
import HeaderNavigator from './element/HeaderNavigator';
import LoginForm from "./element/LoginForm";
export default {
name: 'app',
components: {
LoginForm,
HeaderNavigator
},
computed: {
api() {
return this.$store.state.api;
}
},
data() {
return {
defaultIndex: window.location.path,
defaultIndexProp: window.location.path,
}
},
methods: {
toList() {
this.defaultIndexProp = '/list/';
}
},
mounted() {
this.axios.get('/api/init/').then(r => {
const {data} = r;
this.$store.commit('multiSet', {value: data});
});
}
}
</script>
<style>
</style>
Тот самый файл, в котором уже нужен загруженный список роутов из $store.state.api
ItemsList.vue<template>
<el-card></el-card>
</template>
<script>
export default {
name: 'ItemsList',
data() {
return {
}
},
computed: {
api() {
return this.$store.state.api;
}
},
created() {
this.axios({
url: this.api.items.path,
method: this.api.items.method
}).then(r => {
const {data} = r;
this.$store.commit('multiSet', {value: data});
}).catch(e => {
});
}
}
</script>
<style lang="stylus">
</style>
Вот так выглядит загруженный список роутов: И еще одна особенность, которая, собственно, вгоняет в полный ступор:
Если вывести в компоненте ItemsList.vue сам объект api, находящийся в $store.state, и, по идее, уже заполненный данными, то будет
но если вывести сам $store.state, то в нем объект api будет заполнен данными как и надо:
Вопрос, скорее, не только к частному случаю, можно было и просто записать сразу все роуты в начальное состояние state'a, но получать список роутов с бека намного удобнее, как и обращаться к ним, как к объектам, да и узнать хочу, как правильно делать асинхронные запросы, предзагружать данные и тд. Если что-то в моем вопросе слишком банальное, не кидайте тапки...