Multi-page Application done better with Laravel, Vue and, Vite pt. III
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 @section
s e.g. the title
and content
sections besides, @push
ing content to different @stack
s 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 theresources/js
orresources/scss
directory.
First is the common.js
file which statically import
s 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 import
ing 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.