Multi-page Applications done right in Laravel and Vue. Part III

Mohyaddin Alaoddin
5 min readOct 8, 2022

This is the final part of the story, if you haven’t read the previous parts of it you should read Part I then, Part II.

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. JavaScript and Stylesheets

Last but not least the JavaScript that will accomplish two major points for our web application to function:

  • Bundle the required libraries and Vue components.
  • Define and execute the required business logic of the page.

Thus for each conventional blade view we have; we’ll create a JavaScript file that does those two points mentioned, before we get into an example for such files, let’s have a quick detour for handling stylesheets, most likely we’ll be using one of the most popular UI frameworks e.g. bootstrap or, tailwind but, for further customization we’d have our custom stylesheets in sass and / or scss stored in the resources/scss directory and, Laravel Mix will take care of compiling those files into compressed production-ready css files in the public/css directory.

And that’s it, if you’re following the previous blade example you’d find that the required dashboard script file is accessed by asset(mix(public_path/filename)) call, same case is with stylesheets, so according to that example the required JavaScript file is located in public/js/dashboard.js, thus anything under public directory can be directly accessed using the asset plus mix helper functions — in any Laravel project — without the public/ prefix.

Now, let’s take a look at the JavaScript that operates the previous blade view:

First is the common.js file which bundles some common Vue components for us to be used in all our pages, we’ll consider that bundle as a reusable general components that’s why it’s located in resources/components rather than resources/js.

Then for the dashboard.js file which is located in resources/js, it requires all the necessary Vue components by the import statements, creates our Vue instance then, when all components are successfully loaded it mounts the Vue instance into our DOM.

Two takeaways to consider in the example above, first is the libraries variable which is simply an object that has Vue component names as keys and, imported component definitions as values, any component passed without enclosing braces indicates a group of components e.g. VueTable is a group of components located in resources/components/table directory including an index.js file while, Counter is a component located in resources/components/counter.vue SFC file.

Second, you’ll notice two types of import, static imports which are at the beginning of the file, those will import the exported Vue component definitions into our bundle directly, thus when we build this dashboard.js file the compiled version of it will include those components’ definitions and templates.

The other import at the end of the file is a dynamic import and, it represents one of the approaches to code splitting, as the imported file will be dynamically loaded into our page when it runs on the browser, such dynamic imports will have the required files compiled in separate JavaScript files — called chunks — then, whenever a chunk is needed by our page the browser will request it from server and, once the chunk’s content is retrieved the closure — anonymous function — passed to the then method of the import will be executed.

Finally the passed variable in that closure would include the exported object or function retrieved from that chunk.

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 and, ready to be used within your blade views via the asset(mix()) call.

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.

--

--