If you have been coding along with the examples so far, close your browser now until next chapter, as the following advanced snippets can't simply be included in a browser script.
Advanced features
Single-file components
A drawback of using components is that you need to write your template in a JavaScript string outside of your main HTML file. There are ways to write template definitions in your HTML file, but then you have an awkward separation between markup and logic.
A convenient solution to this is single-file components:
<template> <li v-on:click="bought = !bought" v-bind:class="{ bought: bought }"> <div>{{ title }}</div> </li> </template> <script> export default { props: [ 'title' ], data: function() { return { bought: false }; } } </script> <style> .bought { opacity: 0.5; } </style>
These files have the .vue extension and encapsulate the component template, JavaScript configuration, and style all in a single file.
Of course, a web browser can't read these files, so they need to be first processed by a build tool such as Webpack.
Module build
As we saw earlier, Vue can be dropped into a project as an external script for direct use in a browser. Vue is also available as an NPM module for use in more sophisticated projects, including a build tool such as Webpack.
If you're unfamiliar with Webpack, it's a module bundler that takes all your project assets and bundles them up into something you can provide to the browser. In the bundling process, you can transform those assets as well.
Using Vue as a module and introducing Webpack opens possibilities such as the following:
- Single-file components
- ES feature proposals not currently supported in browsers
- Modularized code
- Pre-processors such as SASS and Pug
Server-side rendering
Server-side rendering is a great way to increase the perception of loading speed in full-stack apps. Users get a complete page with visible content when they load your site, as opposed to an empty page that doesn't get populated until JavaScript runs.
Say we have an app built with components. If we use our browser development tool to view our page DOM after the page has loaded, we will see our fully rendered app:
<div id="app"> <ul> <li>Component 1</li> <li>Component 2</li> <li> <div>Component 3</div> </li> </ul> </div>
But if we view the source of the document, that is, index.html, as it was when sent by the server, you'll see it just has our mount element:
<div id="app"></div>
Why? Because JavaScript is responsible for building our page and, ipso facto, JavaScript has to run before the page is built. But with server-side rendering, our index file includes the HTML needed for the browser to build a DOM before JavaScript is downloaded and run. The app does not load any faster, but content is shown sooner.