How to load all server side data on initial vue.js / vue-router load? How to load all server side data on initial vue.js / vue-router load? wordpress wordpress

How to load all server side data on initial vue.js / vue-router load?


My approach is to delay construction of the store and main Vue until my AJAX call has returned.

store.js

import Vue from 'vue';import Vuex from 'vuex';import actions from './actions';import getters from './getters';import mutations from './mutations';Vue.use(Vuex);function builder(data) {  return new Vuex.Store({    state: {      exams: data,    },    actions,    getters,    mutations,  });}export default builder;

main.js

import Vue from 'vue';import VueResource from 'vue-resource';import App from './App';import router from './router';import store from './store';Vue.config.productionTip = false;Vue.use(VueResource);Vue.http.options.root = 'https://miguelmartinez.com/api/';Vue.http.get('data')  .then(response => response.json())  .then((data) => {    /* eslint-disable no-new */    new Vue({      el: '#app',      router,      store: store(data),      template: '<App/>',      components: { App },    });  });

I have used this approach with other frameworks such as Angular and ExtJS.


You can use navigation guards.

On a specific component, it would look like this:

export default {    beforeRouteEnter (to, from, next) {        // my ajax call    }};

You can also add a navigation guard to all components:

router.beforeEach((to, from, next) => {    // my ajax call});

One thing to remember is that navigation guards are async, so you need to call the next() callback when the data loading is finished. A real example from my app (where the guard function resides in a separate file):

export default function(to, from, next) {    Promise.all([        IngredientTypes.init(),        Units.init(),        MashTypes.init()    ]).then(() => {        next();    });};

In your case, you'd need to call next() in the success callback, of course.


Alright, I finally figured this thing out. All I'm doing is calling a synchronous ajax request within my main.js file where my root vue instance is instantiated, and assigning a data property the requested data as so:

main.js

let acfData;$.ajax({    async: false,    url: 'http://localhost/placeholder/wp-json/acf/v2/page/2',    type: 'GET',    success: function(response) {        console.log(response.acf);        acfData = response.acf;    }.bind(this)})  const router = new VueRouter({    routes: [        { path: '/', component: Home },        { path: '/about', component: About },        { path: '/tickets', component: Tickets },        { path: '/sponsors', component: Sponsors },    ],    hashbang: false});exports.router = router;const app = new Vue({    router,    data: {        acfs: acfData     },    created() {    }}).$mount('#app')

From here, I can use the pulled data within each individual .vue file / component like so:

export default {    name: 'app',    data () {    return {        acf: this.$parent.acfs,    }},

Finally, I render the data within the same .vue template with the following:

<template>  <transition      name="home"      v-on:enter="enter"      v-on:leave="leave"      v-bind:css="false"      mode="out-in"    >    <div class="full-height-container background-image home" v-bind:style="{backgroundImage: 'url(' + this.acf.home_background_image.url + ')'}">      <div class="content-container">        <h1 class="white bold home-title">{{ acf.home_title }}</h1>        <h2 class="white home-subtitle">{{ acf.home_subtitle }}</h2>        <div class="button-block">          <a href="#/about"><button class="white home-button-1">{{ acf.link_title_1 }}</button></a>          <a href="#/tickets"><button class="white home-button-2">{{ acf.link_title_2 }}</button></a>        </div>      </div>    </div>  </transition></template>

The most important piece of information to take away, is that all of the ACF data is only being called ONCE at the very beginning, compared to every time a route is visited using something like beforeRouteEnter (to, from, next). As a result, I'm able to get silky smooth page transitions as desired.

Hope this helps whoever comes across the same problem.