If you want your Vue.js single-page app to communicate with a Laravel backend, you will, quite reasonably, think of using AJAX. Indeed, Laravel comes with the Axios library loaded in by default.
However, it’s not advisable to use AJAX to retrieve application state on the initial page load, as it requires an extra round-trip to the server that will delay your Vue app from rendering.
I see many full-stack Vue/Laravel apps architected in this way. An alternative to this anti-pattern is to inject initial application state into the head of the HTML page so it’s available to the app as soon as it’s needed. AJAX can then be used more appropriately for subsequent data fetches.
Using this approach can get messy, though, if your app has different routes requiring different initial state. In this article, I’ll demonstrate a design pattern that makes it very simple to implement this injection approach, and allows for a lot of flexibility even in multi-route apps.
As you’ll shortly see, an example app I created is interactive 25% sooner when implementing this design pattern.
Passing Data To Vue From Laravel
Here’s an example full-stack Vue/Laravel app I built for Oldtime Cars, a fictitious vintage car retailer. The app has a front page, which shows available cars, and a generic detail page, which shows the specifics of a particular model.
This app uses Vue Router to handle page navigation. Each page needs data from the backend (e.g. the name of the car model, the price etc), so a mechanism for sending it between Vue and Laravel is required. The standard design pattern is to setup API endpoints for each page in Laravel, then use Vue Router’s
beforeRouteEnter hook to asynchronously load the data via AJAX before the page transitions.
The problem with such an architecture is that it gives us this sub-optimal loading process for the initial page load:
Eliminating the AJAX request here would make the page interactive much sooner, especially on slow internet connections.