Multi-page Application done better with Laravel, Vue and, Vite pt. III

Mohyaddin Alaoddin
5 min readMay 1, 2024

This is the final part of our journey in creating a Laravel project with Vue frontend built by Vite, if you haven’t read the preceding parts, you can find them here and here.

V. Conventional Blade Views

These will be the pages that we’d like to show our clients accessing our web application, let’s check the following example of an administration panel dashboard page:

Because we’d like to have a single layout in which our content will be injected into, we use the @extends directive which injects different @sections e.g. the title and content sections besides, @pushing content to different @stacks defined in the master blade view we’ve extended.

You’ll notice in this example that we use both types of components the blade components which their names start with x- e.g. x-tables.refunds and, the Vue component which their names do not have the x- prefix plus, they are not any of the known html tags e.g. the chart tags.

Remember the location that Laravel automatically scans for blade components? In this example the <x-tables.refunds> and other similar tags refer to blade component views stored in resources/views/components/tables directory with names like refunds.blade.php thus, you’ll find the dot . in the tag name that refers to directories of components under the components directory.

You’re totally free to have your blade component under the components directory right away in that case a view named example.blade.php would be included by <x-example> and, to pass props to such components you’ll add them as attributes to the component’s tag as shown in the example, attributes prefixed with a colon : should have variables passed to them but, if an attribute is mentioned without the colon prefix its value will be passed as string into the component.

The major difference between blade and Vue components is that blade components are rendered on server — backend — i.e. their content is injected into the views that refer to them, while Vue components are rendered on client — frontend — by VueJS, it’s important to know which is which especially when you’re debugging or making updates to the UI.

And as Vue component have required attributes to fill, blade components might have their required ones as well so, whenever you get an error that emerges from a blade component’s view, make sure that you’re passing the required variable as an attribute added to the component’s usage tag(s).

VI. The JavaScript that runs it all, beside Stylesheets.

For all mentioned points so far to function we’ll need to develop a javascript file for each traditional blade view — the web page a client accesses as elaborated in the preceding point — , that javascript will import the required vue components’ definitions, templates and, sometimes styling.

As for stand-alone stylesheets they can be included in Vite’s build process as shown in the first part of this article and then, fetched in the corresponding webpage as shown in the previous blade example using the @vite directive — same goes for fetching per page javascript file in the end of the previous example — so, without further ado let’s look into how that script and its dependencies are handled.

Note: the file location used in the @vite directive is relative to the project’s root directory and, refers to the original source file i.e. in the resources/js or resources/scss directory.

First is the common.js file which statically imports some common javascript libraries and vue components to be used in all our pages so, we have defined and exported the functions load, loadBundles and, loadComponents, which executes the loading when called from within the main vue instance passed to each of them in the app parameter.

The loadBundle function takes an array of exported bundles where each bundle is a group of vue components that can be added to our main vue instance via the bundle’s load function — an example of a bundle index.js file is shown at the end of point III in the previous part of this article.

Lastly loadComponents function dynamically loads required vue components into our main vue instance, and because of the use of dynamic import we had to use the defineAsyncComponent vue function which loads the required components when they are actually used on our view — allowing Vite to break down the source into multiple reusable chunks a.k.a code splitting which enhances performance and load times in the process.

The other javascript file is dashboard.js which operates and runs the frontend logic for the dashboard.blade.php blade view explained in the preceding point above, it’s a standard vue app initialized using the createApp vue function using the vue’s options API for simplicity.

Bootstrap and jQuery are already loaded in the common.js file, and the dashboard script is in turn importing common.js, as you can notice the three functions exported from common.js are used before mounting our vue app instance to load chart and counter vue components and, the vue tables components bundle.

daterangepicker and moment were also imported as they are required by various components in the page and, the jQuery and, bootbox methods are used to provide these libraries to the vue components in the page wherever they need them, like in the mounted method defined in the example shown in point III of this article’s previous part.

Conclusion

And that’s finally it, just by running on terminal npm run development if you’d like to test or npm run production if you’d like to go live, you’ll have all your JavaScript files and stylesheets compiled into public/build directory and, ready to be used within your blade views via the @vite call, using the original source file locations e.g. @vite(['resources/js/dashboard.js']) and, vite — Laravel plugin — will automatically pick up the right files for you from the build directory. And yes you can pass multiple source files to the @vite directive whether they’re javascript files or stylesheets.

Feel free to use dynamic imports the way you see fit, you can defer loading big chunks of JavaScript that would increase your pages load times if they were imported statically, besides you might avoid a lot of dead code inclusion using that approach.

This whole workflow could work with other frontend and backend frameworks as well — with some adjustments of course — so, keep exploring and discovering, I know this story has been painfully long but, I hope it has provided you with some guide lines to improve your development experience and, finally I appreciate your interest and your time reading it.

--

--