Single-file components
Introduction#
In the last chapter we briefly covered how Vue lets us organize our app into components which can be used and manipulated in the view.
In this chapter, we'll be diving in deeper into building components with Vue. We'll investigate a pattern that we'll be be able to use to scale Vue apps from scratch. We'll be using this pattern to create an app interface that manages events within a weekly calendar.
In our weekly calendar app, a user can add, delete, and edit day to day events within a week. Each event corresponds to a particular task/to-do item that the user would like to keep track of:

Setting up our development environment#
Node.js and npm#
For this project (and the majority of projects) in this book, we'll need to make sure we have a working Node.js development environment along with the Node Package Manager (npm
).
There are a couple different ways we can install Node.js so please refer to the Node.js website for detailed information: https://nodejs.org/download/.
It's also possible to install Node.js using a tool like nvm or the n tool. Using a package like these allow us to maintain multiple version of node in our development environment.
If you're on a Mac, your best bet is to install Node.js directly from the Node.js website instead of through another package manager (like Homebrew). Installing Node.js via Homebrew is known to cause some issues.
If you're on a Windows machine, you would need to install Node.js through the Windows Installer from the Node.js website.
The easiest way to verify if Node.js has been successfully installed is to check which version of Node.js is running. To do this, we'll open a terminal window and run the following command:
$ node -v
npm is installed as a part of Node.js. To check if npm is available within our development environment, we can list the version of our npm binary with:
$ npm -v
In either case, if a version number is not printed out and instead an error is emitted, make sure to download a Node.js installer that includes npm and ensure that the PATH
is set appropriately.
Vue syntax highlighting#
In this chapter, we'll be introducing Vue single-file components. These components allow us to write Vue code within a new file format - .vue
. Depending on your code editor, you may need to install a syntax highlighting plugin to simplify the readability of these components. Here are some popular Vue code highlighting plugins for the following editors:
Sublime Text: vue-syntax-highlight
Atom: language-vue-component
Vim: vim-vue
Visual Studio Code: Vetur
Getting started#
As with all chapters, we begin by making sure that we've downloaded the book’s sample code and have it at the ready.
Previewing the app#
Before we start writing any code, let’s see a complete implementation of the app.
In the terminal, let's change into the calendar_app
directory using the cd
command:
$ cd calendar_app
We'll use npm to install all the application's dependencies. These dependencies allow us to write our application using ES6/ES7 as well as include the Vue library. Instead of using the CDN version of Vue, we'll embed the dependency into our application.
Let's install the applications' dependencies:
$ npm install
Now we can start the server using the npm run serve
call (which starts the application in development mode):
$ npm run serve
To preview the complete application, we'll point our browser to the URL http://localhost:8080
. Spend a few minutes playing around with the app to get an understanding of what we'll be building.

Prepare the app#
In our terminal, let's run ls
to see the project’s layout:
babel.config.js
In addition, we have the hidden .gitignore
file in the project directory.
There are significant changes in the structure of this project as compared to our first app. We'll break down each file and directory in the section below.
If you're not familiar with Javascript Webpack projects, don't be deterred from continuing with this chapter. The configuration is good to understand but we'll only be working within the
src/
folder of the application.
README.md
#
All extra information/run steps are listed in the README.md
file.
babel.config.js
#
Babel is a JavaScript transpiler that transpiles ES6 syntax to older ES5 syntax for any browser to understand. The .babel.config.js
file can be used to configure the Babel presets and plugins in our application. This package/setup allows us to transpile all of our .js
files, which subsequently allows us to write with ES6.
node_modules
#
The node_modules
directory refers to all the different JavaScript libraries that have been installed in our application with npm install
.
package.json
{#components_package_json}#
The package.json
file lists all the locally installed npm packages in our application for us to manage. The scripts
portion dictates the npm
commands that can be run in our application.
"serve": "vue-cli-service serve",
For our app, we'll be running npm run serve
in our terminal to run our local Webpack server.
Though we won't be deploying our application in this chapter, npm run build
will use Webpack to bundle our application files to static assets within a dist/
folder. This prepares the dist/
folder to be ready for deployment.
npm run lint
uses ESLint to run through our application source code and identify/report any errors or code that doesn't follow a particular pattern. The patterns our application will lint (i.e. check for) are dictated in the eslintConfig
field of package.json
.
The overview of code to identify and report any errors or disorder is known as linting. The primary reason behind linting is to ensure code quality by verifying code is both free of errors and it adheres to certain code standards/practices.
Notice how each script
runs a command that starts with vue-cli-service
? The vue-cli-service
is a development dependency that is installed to each and every project scaffolded with the Vue CLI. This service, built on top of webpack and webpack-dev-server, introduces the commands for us to build
, lint
, test
, and serve
our application.
The Vue CLI scaffolds a standard Webpack configuration that's able to be used by most Vue applications. If customization needs to be done to this out-of-the-box configuration, the vue-cli
gives us the ability to do so in fine-grained manner. Though we won't be making any customizations to the scaffold in this chapter, you can read more details in the Configuration Reference section of the vue-cli
docs.
Let's quickly address the dependencies that have been installed in our application.
We have the vue
library as the main dependency:
"vue": "^3.0.0"
And a series of build libraries as the devDependencies
:
"@vue/cli-plugin-eslint": "~4.5.0",
@vue/cli-service
installs the vue-cli-service
binary.
@vue/cli-plugin-babel
and @vue/cli-plugin-eslint
are plugins that have been introduced in to our application. In the vue-cli
, plugins can be used to add additional features to a project by modifying the internal Webpack configuration. @vue/cli-plugin-babel
is a plugin that introduces Babel to help transpile ES6 JavaScript down to ES5. @vue/cli-plugin-eslint
is used to introduce ESLint into our application.
node-sass
and sass-loader
helps compile SCSS to CSS within a node development environment.
@vue/compiler-sfc
is a package to help compile Vue single-file components.
In a Node.js environment,
devDependencies
are the packages needed only during development whiledependencies
are often needed for both development and production.
In the package.json
file, there also exists the eslintConfig
and browserslist
fields:
eslintConfig
lists the details of our applications ESLint configuration. In the Vue CLI, ESLint can be configured with the eslintConfig
field in package.json
or a separate .eslintrc
file.
browserslist
declares the browsers our application is targeting. The details in browserslist
is used by both our application's babel configuration (to determine the appropriate JavaScript transpilation) as well as autoprefixer (to determine the appropriate CSS vendor prefixes).
public/
#
The public/
folder hosts the bulma/
and font-awesome/
libraries that we'll use in our application.
In addition, public/
contains the index.html
file which represents the root markup page of our application. This file is where we specify the external stylesheet dependencies as well as the DOM element where the Vue instance is to be mounted.
The index.html
file:
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
In the <body></body>
element, the <no-script></no-script>
tag displays a message to the user that states the application won't work as intended if JavaScript is disabled in the browser.
The built files will be auto injected
comment references the fact that in the production build (i.e. the dist/
folder that's generated from the application build script), the app configuration will auto inject the built files into the index.html
file.
src/
#
The src/
directory contains the JavaScript files that we'll be working directly with:
app-complete/
We'll be building our app inside app/
. Each significant step we take along the way is included here: app-1/
, app-2/
, and so forth.
Like the last chapter, code examples in the book are titled with the file in which the example is defined.
Our main.js
file dictates the starting point of our application. main.js
is where we mount our Vue instance to the DOM element with an id of #app
, the declared DOM element in our index.html
file.
We also import and specify the component App.vue
to be the root-level parent component rendered in our Vue application.
This lesson preview is part of the Fullstack Vue course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Fullstack Vue, plus 0+ \newline books, guides and courses with the \newline Pro subscription.
