Fullstack Vue
The Complete Guide to Vue.js and Friends
Wri!en by Hassan Djirdeh, Nate Murray, and Ari Lerner
© 2018 Fullstack.io
All rights reserved. No portion of the book manuscript may be reproduced, stored in a retrieval
system, or transmi!ed in any form or by any means beyond the number of purchased copies,
except for a single backup or archival copy. "e code may be used freely in your projects,
commercial or otherwise.
"e authors and publisher have taken care in preparation of this book, but make no expressed
or implied warranty of any kind and assume no responsibility for errors or omissions. No
liability is assumed for incidental or consequential damagers in connection with or arising out
of the use of the information or programs container herein.
Published in San Francisco, California by Fullstack.io.
FULLSTACK
.io
Contents
Book Revision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Be notified of updates via Twitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
We’d love to hear from you! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
How to Get the Most Out of This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Vue 2.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Running Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Code Blocks and Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Instruction for Windows users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Emailing Us . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Get excited! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
I - Your first Vue.js Web Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Building UpVote! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Development environment setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
JavaScript ES6/ES7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Setting up the view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Making the view data-driven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
List rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Event handling (our app’s first interaction) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
v-bind and v-on shorthand syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Congratulations! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
II - Single-file components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Setting up our development environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
CONTENTS
Single-File Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Breaking the app into components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Managing data between components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Simple State Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Steps to building Vue apps from scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Step 1: A static version of the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Step 2: Breaking the app into components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Step 3: Hardcode Initial States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Step 4: Create state mutations (and corresponding component actions) . . . . . . . . . . . . 75
The Calendar App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Methodology review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
III - Custom Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
JavaScript Custom Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Vue Custom Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Event Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Custom events and managing data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
IV - Introduction to Vuex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
What is Flux? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Flux implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Vuex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Refactoring the note-taking app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Vuex Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Building the components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
V - Vuex and Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
The Server API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Playing with the API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Client and server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Preparing the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
The Vuex Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
productModule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
cartModule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Interactivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Vuex and medium to large scale applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
VI - Form Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
CONTENTS
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Forms 101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
The Basic Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Text Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Multiple Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Validations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Async Persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Vuex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Form Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
VII - Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
What is routing? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
URL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Single-page applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Basic Vue Router . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Dynamic Route Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
The Server API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Starting point of the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Integrating vue-router . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Supporting authenticated routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Implementing login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Vue Watchers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Navigation Guards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Recap and further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
VIII - Unit Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
End-to-end vs. Unit Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
Testing tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Testing a basic Vue component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Testing App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
vue-test-utils . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
More assertions for App.vue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Writing tests for a weather app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
IX - Fullstack Vue Screencast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Building SimpleCoinCap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Agenda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431