My Singular Vue Reference
April 19, 2020 (updated: July 05, 2020)
The deeper I get into learning Vue, the more notes I have to take 😄 I’m getting a bit annoyed with combing through my separate Vue posts to find information, so I’ll condense everything here instead. This post will be a straight copy-paste job from some of my previous posts, and I’ll add new information in the future as I learn it.
Table of Contents
- My Favorite Vue Resources
- Installing Vue & Vue UI
- Creating A Vue Project
- Creating A Project via CLI
- Basic Component Structure
- Passing Props
- Form Input Binding & Debouncing
- Vue Router
- Vetur & Formatting
My Favorite Vue Resources
These are the websites and repos that have taught me Vue.
- Vue Docs
- Vue Docs - Component Lifecycle Diagram
- Vue CLI Docs
- Vuetify Docs (Vue implementation of Material Design)
- Vuex Docs
- Vue Router Docs
My Vue Learning Repos
- Basic Vue using the CDN - event handling, data binding, conditionals & loops, component basics, references
- Real-world Vue using the CLI and NPM - global components, nested components, props, references
- Basic Blog Example - forms, Axios, custom directives, filters, mixins, Vue Router
- Minimal Vuetify Sandbox
Video Courses I Found To Be Very Helpful
- The Net Ninja’s Vue Course
- Brad Traversy Vue Crash Course
- 7 Secret Patterns Vue Consultants Don’t Want You to Know — talk, and accompanying repo
- The NetNinja’s Vuex Course and accompanying repo
- Vuex: A Deeper Look At Modules, Namespacing and More and accompanying repo
- The NetNinja’s Vuetify Course — NOTE: this course is for Vuetify v1…good for an overview but there were a lot of changes in v2
Useful Blog Posts On Various Topics
- How to query your API using Vuex in your Vue application
- Data vs Computed vs Watcher in Vue Components
Vue + TypeScript
- Here’s a video intro’ing TypeScript particularly with Vue (note: it demos using Classes in Vue, which has been phased out).
- This series is a tutorial similar to Traversy’s above, but implementing TypeScript
- This video demonstrates a basic Vue app, comparing the vanilla JS way, the Class way, and the TypeScript way
Courses I May Find Useful In The Future
- Vue Mastery Courses (paid)
- Building a VueJS screencasting app from scratch
- Brad Traversy’s Full Stack Vue App Tutorial
- freeCodeCamp 3-hr Intro to Vue
- How to code a BLOG in VueJS & NodeJS - A guy coding a Vue app during his 100DaysOfCode. This is one video of a few about Vue.
Installing Vue & Vue UI
To install Vue:
npm install -g @vue/cli
The main tutorial I’m doing this with showed a cool demo of Vue UI so I thought I’d try it out. So next step to create the actual Vue app is to invoke it:
Creating A Vue Project
…and then create a new project. This walks you through a bunch of steps; I did:
- named the client app ‘client’ making sure I’m in the app’s parent folder
- selected npm as my package manager (it’s the default I later learned…not necessary to change)
- unticked the option to create a git repo…it’s already in a git repo
- chose a manual preset in order to be able to add TypeScript
- added TypeScript as an enabled feature
- unticked the option to use class-style component syntax
- chose which ESLint option to install (‘error prevention only’ to go the minimal style, but whatever option is comfortable is fine)
- Create Project!
It took a while to install, but created the app in the end. Then you can run it from the UI in the Tasks tab, and clicking serve then Run task. Otherwise run
npm run serve (assuming npm) from the command line in the client directory.
For the first time it will take a little while for the build to complete, but when it does you can visit the app at
localhost:8080 (or just click the **Open app button in the CLI). Also not a bad idea to
git commit the installation here before making any customizations.
A few initial things I noticed using the UI tool…
- To see the console output (including any runtime errors), open Tasks –> Output
Plugins and utilities like Vuetify, Vue Router, and Vuex can be added from the Vue GUI:
- Go to the Plugins tab
- Click ‘add plugin’
- Search for *vuetify (or whatever plugin) and then click
vue-cli-plugin-vuetifywhen it comes up, and install it
- Leave the default preset and the click Finish installation and let it do its installation magic
Creating A Project via CLI
$ cd to/parent/directory/of/vue/app
Go through the options as prompted.
Basic Component Structure
Every Vue component is made up of three basic building blocks:
<template></template>— Vue-ified HTML of how the component should actually be structured
<script></script>— import utilities and export data, methods, etc. for each component
<style></style>— style the bad boy
One important thing to note about the
style element: adding the scoped attribute limits CSS to this component only:
The simple way to register props that have been passed down to a component is to list them in an array:
This is acceptable, but best practice says it’s better to be more specific about prop types, defaults, and requirements to reduce bugs, errors, omitted props, etc. You can also add validators to further defend against human error.
Form Input Binding
One important thing to know:
v-model overwrites the
value attribute on text elements, so it’s not necessary to include.
Note: This is not true for checkboxes or radios, you still need the
I was used to doing this out of habit, and also Emmet auto-complete…must remember to remove this attribute when creating forms!
The same is true for adding the
selected attributes to checkboxes and selects. See docs.
By the way, I guess you don’t need the
name element either? Since it’s used to organize data going to the serve, but with Vue the data model handles that instead.
.lazy Modifier is Great! Replaces Debouncing
In React (from what I know) it’s a complicated process to debounce user input, i.e. stop the form from acting on the input with every key press. Vue has this cool
.lazy modifier which means it won’t react to the input data until focus changes away from the input. Example:
Vue Router - How Routing Works in History Mode
Normally when a URL has a slash in it, or a path, it sends a request to the server:
Vue by default allows for routing in “hash mode”…the hash is used to prevent the browser from making a new server request:
But this is lame! So instead
vue-router needs to be set up in history mode so that no matter the path, the index.html file will be loaded. See docs.
One important thing to note—history-mode routing works by default in development mode when running
npm run serve, but in production there is some extra configuration to do depending on the production setup.
Vuex is a state manager that sits across an entire application (similar to Redux in React world). I watched the NetNinja’s Vuex tutorial playlist to get acquainted with it.
This article is a good example of using Vuex to implement a global flash alert, aka snackbar.
Vuetify is a component library which implements the Material Design principles for Vue apps. One thing I saw that I might like to try is implementing a dark theme toggle. You can do this by adding a button control in
App.vue which calls a method:
<v-btn @click="toggleTheme">Toggle Theme</v-btn>
The method is simple too:
Here are the docs to see which properties can be customized in a theme.
Vetur & Formatting
Vetur is a VS Code plugin that takes care of syntax highlighting and formatting in Vue files. It did one really annoying thing that always bothered me and I finally figured out how to fix it.
prettier-html as the default formatter for the
<template> sections of Vue files, and this formatter by default wraps element attributes so they look like this:
I hate this.
It took a while to figure out what was actually doing this (Vuetify? ESLint? Some other VS Code setting?) but finally this article illuminated everything. Long story short the solution was to change the Vetur formatter for HTML from
js-beautify-html and then to tell it not to wrap attributes.
In learning that Vetur was injecting Prettier formatting into the files, I was also able to adjust some other things that had been niggling, though not so strongly. The final settings I added to my VS Code settings.json were: