I'm currently making use of the WordPress REST API, and vue-router to transition between pages on a small single page site. However, when I make an AJAX call to the server using the REST API, the data loads, but only after the page has already rendered.
The vue-router documentation provides insight in regards to how to load data before and after navigating to each route, but I'd like to know how to load all route and page data on the initial page load, circumnavigating the need to load data each time a route is activated.
Note, I'm loading my data into the acf
property, and then accessing it within a .vue
file component using this.$parent.acfs
.
main.js Router Code:
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: ''
},
created() {
$.ajax({
url: 'http://localhost/placeholder/wp-json/acf/v2/page/2',
type: 'GET',
success: function(response) {
console.log(response);
this.acfs = response.acf;
// this.backgroundImage = response.acf.background_image.url
}.bind(this)
})
}
}).$mount('#app')
Home.vue Component Code:
export default {
name: 'about',
data () {
return {
acf: this.$parent.acfs,
}
},
}
Any ideas?
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
From here, I can use the pulled data within each individual
.vue
file / component like so:Finally, I render the data within the same
.vue
template with the following: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.
My approach is to delay construction of the store and main Vue until my AJAX call has returned.
store.js
main.js
I have used this approach with other frameworks such as Angular and ExtJS.
Check this section in docs of Vue Router
https://router.vuejs.org/guide/advanced/data-fetching.html
So first of you have to write method that would fetch data from your endpoint, and then use watcher to watch route.
Since you are working with WP Rest API, feel free to check my repo on Github https://github.com/bedakb/vuewp/blob/master/public/app/themes/vuewp/app/views/PostView.vue#L39
You can use navigation guards.
On a specific component, it would look like this:
You can also add a navigation guard to all components:
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):In your case, you'd need to call
next()
in thesuccess
callback, of course.