Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of contents

Table of Contents

...

  • The Official Vue.js Guide

    • Expand


      • Installation - Dev (with warnings), Production (minified, no warnings)
      • Getting Started - Some simple examples: Two-way binding, rendering a list, and handling user input.
      • Overview - Vue is a library for building interactive web interfaces. The goal of Vue.js is to provide the benefits of reactive data binding and composable view components with an API that is as simple as possible.
        • Reactive Data Binding - We use special syntax in our normal HTML templates to “bind” the DOM to the underlying data. Once the bindings are created, the DOM will then be kept in sync with the data. This makes our code easier to write, easier to reason about and easier to maintain.
          • A 'ViewModel' is a Vue instance which links the view and the model.
          • "Directives" are special attributes provided by Vue.js,. They apply special reactive behavior to the rendered DOM. (ex: "v-if")
          • Not only can we bind DOM text to the data, we can also bind the structure of the DOM to the data. (ex: removing elements)
        • Component System - This is an abstraction that allows us to build large-scale applications composed of small, self-contained, and often reusable components.
      • The Vue Instance
        • Constructor - Every Vue.js app is bootstrapped by creating a root Vue instance with the Vue() constructor function. A Vue instance is essentially a ViewModel as defined in the MVVM pattern, hence the variable name vm you will see throughout the docs.

          • When you instantiate a Vue instance, you need to pass in an options object which can contain options for data, template, element to mount on, methods, lifecycle callbacks and more.
          • The Vue constructor can be extended to create reusable component constructors with pre-defined options. All Vue.js components are essentially extended Vue instances.
          • I didn't understnd this: "Although you can create extended instances imperatively, in most cases you will be registering a component constructor as a custom element and composing them in templates declaratively."
        • Properties and Methods

          • Each Vue instance proxies all the properties found in its data object. (that is, those properties are reactive)
          • If you attach a new property to the instance after it has been created, it will not trigger any view updates.
          • In addition to data properties, Vue instances expose a number of useful instance properties and methods. These properties and methods are prefixed with $ to differentiate from proxied data properties.
        • Instance Lifecycle

          • Each Vue instance goes through a series of initialization steps when it is created.
          • Along the way, it will also invoke some lifecycle hooks, which give us the opportunity to execute custom logic.
          • There are also other hooks which will be called at different stages of the instance’s lifecycle.
          • Some users may have been wondering where the concept of “controllers” lives in the Vue.js world, and the answer is: there are no controllers in Vue.js. Your custom logic for a component would be split among these lifecycle hooks.
        • Lifecycle Diagram

          • Lifecycle
      • Data Binding Syntax - Vue.js uses a DOM-based templating implementation. This means that all Vue.js templates are essentially valid, parsable HTML enhanced with some special attributes.
        • Interpolations
          • Text
            • Example: <span>Message: {{ msg }}</span>
            • You can also perform one-time interpolations that do not update on data change: {{* msg }}
          • Raw HTML
            • In order to output real HTML, you will need to use triple mustaches: <div>{{{ raw_html }}}</div>
            • I didn't understand this: If you need to reuse template pieces, you should use partials.
            • Only use HTML interpolation on trusted content and never on user-provided content.
          • Attributes
            • Mustaches can also be used inside HTML attributes: <div id="item-{{ id }}"></div>
        • Binding Expressions - The text we put inside mustache tags are called binding expressions. In Vue.js, a binding expression consists of a single JavaScript expression optionally followed by one or more filters.
          • JavaScript Expressions
            • Example: {{ message.split('').reverse().join('') }}
            • Expressions are evaluated in the data scope of the owner Vue instance.
            • Each binding can only contain one expression.
          • Filters
            • Example: {{ message | capitalize }}
            • Vue.js provides a number of built-in filters.
            • The pipe syntax is not part of JavaScript syntax, therefore you cannot mix filters inside expressions; you can only append them at the end of an expression.
            • Filters can be chained.
            • Filters can take arguments.
              • The filter function always receives the expression’s value as the first argument.
              • Quoted arguments are interpreted as plain string.
              • Un-quoted arguments are evaluated as expressions.
        • Directives - Directives are special attributes with the v- prefix. A directive’s job is to reactively apply special behavior to the DOM when the value of its expression changes.
          • Arguments - Some directives can take an “argument”, denoted by a colon after the directive name.
          • Modifiers - Modifiers are special postfixes denoted by a dot, which indicate that a directive should be bound in some special way.
        • Shorthands - Vue.js provides special shorthands for two of the most often used directives, v-bind and v-on.
          • v-bind Shorthand - v-bind:argument_name can be shortened to :argument_name.
          • v-on Shorthand - on:event_name can be shortened to @event_name
      • Computed Properties - In-template expressions are very convenient, but they are really meant for simple operations only. Templates are meant to describe the structure of your view. Putting too much logic into your templates can make them bloated and hard to maintain. This is why Vue.js limits binding expressions to one expression only. For any logic that requires more than one expression, you should use a computed property.
        • Basic Example

        • Computed Property vs. $watch - It is often a better idea to use a computed property rather than an imperative $watch callback.

        • Computed Setter - Computed properties are by default getter-only (meaning input variables are watched and used to "get" an updated output variable), but you can also provide a setter when you need it (meaning the "output" is updated and the corresponding input variables are then updated to match the output).

      • Class and Style Bindings - A common need for data binding is manipulating an element’s class list and its inline styles.  Vue.js provides special enhancements when v-bind is used for class and style.
        • Binding HTML Classes
          • Object Syntax - We can pass an Object to v-bind:class to dynamically toggle classes.
            • Exampel: <div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB }"></div>
            • We can bind to a computed property that returns an Object. This is a common and powerful pattern.
          • Array Syntax - <div v-bind:class="[classA, classB]">
        • Binding Inline Styles
          • Object Syntax - <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
            • It is often a good idea to bind to a style object directly so that the template is cleaner.
          • Array Syntax - <div v-bind:style="[styleObjectA, styleObjectB]">
          • Auto-prefixing - I didn't understand this: When you use a CSS property that requires vendor prefixes in v-bind:style, for example transform, Vue.js will automatically detect and add appropriate prefixes to the applied styles.
      • Conditional Rendering
        • v-if: <h1 v-if="ok">Yes</h1>
        • Template v-if - What if we want to toggle more than one element? In this case we can use v-if on a <template> element, which serves as an invisible wrapper. 
        • v-show - An element with v-show will always be rendered and remain in the DOM; v-show simply toggles the display CSS property of the element.
        • v-else - You can use the v-else directive to indicate an “else block” for v-if or v-show. The v-else element must immediately follow the v-if or v-show element - otherwise it will not be recognized.
          • Component caveat - When used with components and v-show, v-else doesn’t get applied properly due to directives priorities. Instead of using v-else, use another v-show where the condition is the opposite of that in the first v-show.
        • v-if vs. v-show - Prefer v-show if you need to toggle something very often, and prefer v-if if the condition is unlikely to change at runtime.
      • List Rendering
        • Intro
          • v-for - <li v-for="item in items">
          • Inside v-for blocks we have full access to parent scope properties, plus a special variable $index which is the Array index for the current item
        • Template v-for - You can use a <template> tag with v-for to render a block of multiple elements.
        • Array Change Detection
          • Mutation Methods - Vue.js wraps an observed Array’s mutation methods so they will also trigger View updates.
          • Replacing an Array - There are also non-mutating methods, e.g. filter(), concat() and slice(), which do not mutate the original Array but always return a new Array. When working with non-mutating methods, you can just replace the old Array with the new one.
          • track-by - In some cases, you might need to replace the Array with completely new objects. Since by default v-for determines the reusability of existing scopes and DOM elements by tracking the identity of its data object, this could cause the entire list to be re-rendered. However, if each of your data objects has a unique id property, then you can use a track-by special attribute to give Vue.js a hint so that it can reuse existing instances as much as possible.
          • track-by $index - If you don’t have a unique key to track by, you can also use track-by="$index", which will force v-for into in-place update mode. Be careful if the v-for block contains form input elements or child components.
          • Caveats
            • Due to limitations of JavaScript, Vue.js cannot detect the following changes to an Array:
              • When you directly set an item with the index, e.g. vm.items[0] = {};
                • To deal with this, Vue.js augments observed Arrays with a $set() method.
              • When you modify the length of the Array, e.g. vm.items.length = 0
                • To deal with this, just replace 'items' with an empty array instead.
            • Vue.js also augments Arrays with a convenience method $remove(), which searches for and removes an item from target Array by calling splice() internally.
            • I don't understand this: When iterating over an array of objects frozen with Object.freeze(), you need to explicitly use a track-by key.
        • Object v-for - You can also use v-for to iterate through the properties of an Object. In addition to $index, each scope will have access to another special property $key.
        • Range v-for - v-for can also take an integer Number. In this case it will repeat the template that many times.
        • Displaying Filtered/Sorted Results  - There are two options to achieve this:
          1. Create a computed property that returns the filtered or sorted Array;
          2. Use the built-in filterBy and orderBy filters.
      • Methods and Event Handling
        • Method Handler - We can use the v-on directive to listen to DOM events.
          • The example is passed an 'event' argument automatically since just the function name is listed.
          • `this` inside methods point to the Vue instance
        • Inline Statement Handler - Instead of binding directly to a method name, we can also use an inline JavaScript statement.
          • In this example they call a function with an argument.
          • You can still pass the event object using the special $event variable.
        • Event Modifiers - Vue.js provides event modifiers for v-on: .prevent, .stop, .capture, and .self.
          • I found this section hard to understand because I didn't understand the context: "It is a very common need to call event.preventDefault() or event.stopPropagation() inside event handlers. Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details."
        • Key Modifiers - This simplifies handling keyboard presses: <input v-on:keyup.enter="submit">
        • Why Listeners in HTML?
          • It makes it easier to locate the handler function implementations within your JS code by simply skimming the HTML template.
          • Since you don’t have to manually attach event listeners in JS, your ViewModel code can be pure logic and DOM-free. This makes it easier to test.
          • When a ViewModel is destroyed, all event listeners are automatically removed. You don’t need to worry about cleaning it up yourself.
      • Form Input Bindings - Review this, maybe code up some examples to play with.
        • Basics Usage - You can use the v-model directive to create two-way data bindings on form input and textarea elements. This section is just a collection of simple examples: Text, Checkbox, Radio, Select, etc.
        • Value Bindings - If you need the choices to be dynamic or non-strings (ie not just static strings), you can do that with v-bind.
          • I had trouble understanding the examples.
        • Param Attributes
          • lazy - By default, v-model syncs the input with the data after each input event. You can add a lazy attribute to change the behavior to sync after change events.
          • number - If you want user input to be automatically persisted as numbers, you can add a number attribute to your v-model managed inputs.
          • debounce - The debounce param allows you to set a minimum delay after each keystroke before the input’s value is synced to the model. This can be useful when you are performing expensive operations on each update, for example making an Ajax request for type-ahead autocompletion. Note that the debounce param does not debounce the user’s input events: it debounces the “write” operation to the underlying data. Therefore you should use vm.$watch() to react to data changes when using debounce. For debouncing real DOM events you should use the debounce filter.
      • Transitions - With Vue.js’ transition system you can apply automatic transition effects when elements are inserted into or removed from the DOM. To apply transition effects, you need to use the special transition attribute on the target element.
        • CSS Transitions
          • Example
            • You can achieve different transitions on the same element by using dynamic binding.
          • Transition CSS Classes - The classes being added and toggled are based on the value of the transition attribute. In the case of transition="fade", three CSS classes are involved.
            • If the transition attribute has no value, the classes will default to .v-transition, .v-enter and .v-leave.
          • Custom Transition Classes - I didn't understand this: You can specify custom enterClass and leaveClass in the transition definition. These will override the conventional class names. Useful when you want to combine Vue’s transition system with an existing CSS animation library, e.g. Animate.css.
          • Transition Flow Details - Too detailed for where I'm at.
          • CSS Animations - CSS animations are applied in the same way with CSS transitions, the difference being that the v-enter class is not removed from the element immediately after the element is inserted, but on an animationend event.
        • JavaScript Transitions - You can also use just the JavaScript hooks without defining any CSS rules. (I found the example hard to feel fully comfortable with. It wasn't clear to me how the transition would get triggered.)
        • Staggering Transitions - It’s possible to create staggering transitions when using transition with v-for. You can do this either by adding a stagger, enter-stagger or leave-stagger attribute to your transitioned element.
          • A great explanation of staggering animations
            • "When each item's animation is incrementally delayed, they appear as individuals, but still move collectively as a whole. The result is captivating and feels more true to life."
      • Components
        • What are Components? - Components are one of the most powerful features of Vue.js. They help you extend basic HTML elements to encapsulate reusable code. At a high level, Components are custom elements that Vue.js’ compiler would attach specified behavior to. In some cases, they may also appear as a native HTML element extended with the special is attribute. (I don't understand 'they may appear as a native HTML element')
        • Using Components
          • Creation - You can create a component constructor using Vue.extend().
          • Registration - To use a constructor as a component, you need to register it with Vue.component(tag, constructor).
            • Vue.js does not enforce the W3C rules for custom tag-names (all-lowercase, must contain a hyphen) though following this convention is considered good practice.
            • Make sure the component is registered before you instantiate your root Vue instance.
            • Note that components are provided a "template" property instead of mounting with the "el" property. Only the root Vue instance (defined using "new Vue") will include an el to mount to.
          • Local Registration - You can make a component available only in the scope of another component by registering it with the "components" instance option of the parent component instead of using "Vue.component()" to register the child component globally.
          • Registration Sugar - To make things easier, you can directly pass in the options object instead of an actual constructor to Vue.component() and the component option. Vue.js will automatically call Vue.extend() for you under the hood.
          • Component Option Caveats - If you use the 'data' or 'el' properties when defining a component, you're probably going to generally want to set them equal to a function that returns a fresh object for each instance of that component.
          • Template Parsing
            • Some HTML elements have restrictions on what elements can appear inside them.
              • a can not contain other interactive elements (e.g. buttons and other links)
              • li should be a direct child of ul or ol, and both ul and ol can only contain li
              • option should be a direct child of select, and select can only contain option (and optgroup)
              • table can only contain thead, tbody, tfoot and tr, and these elements should be direct children of table
              • tr can only contain th and td, and these elements should be direct children of tr
            • In case of a custom element you should use the "is" special attribute.
            • In case of a <template> inside of a <table> you should use <tbody>, as tables are allowed to have multiple tbody.
        • Props
          • Passing Data with Props
            • Every component instance has its own isolated scope.
            • This means you cannot (and should not) directly reference parent data in a child component’s template.
            • Data can be passed down to child components using props.
            • A “prop” is a field on a component’s data that is expected to be passed down from its parent component.
            • A child component needs to explicitly declare the props it expects to receive using the props option.
            • The prop can be used inside templates, and will also be set as `this.msg`.
          • camelCase vs. kebab-case -  When using camelCased prop names as attributes in an HTML tag, you need to use their kebab-case (hyphen-delimited) equivalents.
            • Example: 'myMessage' → 'my-message'
            • Explanation: HTML attributes are case-insensitive. (So what?)
          • Dynamic Props - You can also use v-bind for dynamically binding props to data on the parent, so that whenever the data is updated in the parent, it will also flow down to the child.
          • Literal vs. Dynamic - If we want to pass down an actual JavaScript number, we need to use the dynamic-prop-syntax ("v-bind:") to make its value be evaluated as a JavaScript expression.
            • This is a common mistake beginners tend to make.
          • Prop Binding Types
            • By default, all props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around.
              • This default is meant to prevent child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to reason about.
              • However, it is also possible to explicitly enforce a two-way or a one-time binding with the .sync and .once binding type modifiers.
            • Important: Note that if the prop being passed down is an Object or an Array, it is passed by reference. Mutating the Object or Array itself inside the child will affect parent state, regardless of the binding type you are using.
          • Prop Validation - It is possible for a component to specify the requirements for the props it is receiving.
            • This is useful when you are authoring a component that is intended to be used by others, as these prop validation requirements essentially constitute your component’s API, and ensure your users are using your component correctly.
            • Instead of defining the props as an array of strings, you can use the object hash format that contain validation requirements.
            • When a prop validation fails, Vue will refuse to set the value on the child component, and throw a warning if using the development build.
        • Parent-Child Communication
          • Parent Chain
            • A child component holds access to its parent component as this.$parent. A root Vue instance will be available to all of its descendants as this.$root. Each parent component has an array, this.$children, which contains all its child components.
            • Although it’s possible to access any instance in the parent chain, you should avoid directly relying on parent data in a child component and prefer passing data down explicitly using props.
            • It is a very bad idea to mutate parent state from a child component.
              • It makes the parent and child tightly coupled.
              • It makes the parent state much harder to reason about when looking at it alone, because its state may be modified by any child! Ideally, only a component itself should be allowed to modify its own state.
          • Custom Events - All Vue instances implement a custom event interface that facilitates communication within a component tree.
            • This event system is independent from the native DOM events and works differently.
            • Each Vue instance is an event emitter that can:
              • Listen to events using $on();
              • Trigger events on self using $emit();
              • Dispatch an event that propagates upward along the parent chain using $dispatch();
              • Broadcast an event that propagates downward to all descendants using $broadcast().
            • I don't understand this: Unlike DOM events, Vue events will automatically stop propagation after triggering callbacks for the first time along a propagation path, unless the callback explicitly returns true.
            • This section has a good example to look over a few times to get comfortable with $dispatch.
            • The `events` option in the parent calls `$on` for you when the instance is created.
          • v-on for Custom Events - v-on can be used to listen for custom events when used on a child component.
            • Example: <child v-on:child-msg="handleIt"></child>
            • When the child triggers the "child-msg" event, the parent’s handleIt method will be called. Any code that affects the parent’s state will be inside the handleIt parent method; the child is only concerned with triggering the event.
          • Child Component Refs - (Seems like an edge case) Despite the existence of props and events, sometimes you might still need to directly access a child component in JavaScript. To achieve this you have to assign a reference ID to the child component using v-ref.
        • Content Distribution with Slots - I found this hard to feel fully comfortable with. I don't understand what is being referred to by "mount target" (is that the <body> tag?). I don't understand when it says "The <app> component very likely has its own template."; isn't that what it just showed above? How can a component ever not have a template?
          • Motivation: We need a way to interweave parent “content” and a component’s own template. This is a process called content distribution (or “transclusion” if you are familiar with Angular).
          • Compilation Scope - Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope.
            • A common mistake is trying to bind a directive to a child property/method in the parent template. If you need to bind child-scope directives on a component root node, you should do so in the child component’s own template.
          • Single Slot - When there is only one slot tag in the child template and the slot tag has no attributes, the entire content fragment from the parent component will be inserted at the position of the slot tag in the DOM, replacing the slot itself.
            • This one has a good example.
          • Named Slots - <slot> elements have a special attribute, name, which can be used to further customize how content should be distributed. You can have multiple slots with different names. A named slot will match any element that has a corresponding slot attribute in the content fragment.
            • There can still be one unnamed slot, which is the default slot that serves as a catch-all outlet for any unmatched content. If there is no default slot, unmatched content will be discarded.
        • Dynamic Components - You can use the same mount point and dynamically switch between multiple components by using the reserved <component> element and dynamically bind to its is attribute.
          • keep-alive - If you want to keep the switched-out components alive so that you can preserve its state or avoid re-rendering, you can add a keep-alive directive param.
          • activate Hook - When switching components, the incoming component might need to perform some asynchronous operation before it should be swapped in. To control the timing of component swapping, implement the 'activate' hook on the incoming component.
            • I don't fully understand the example.
              • Where does the 'data' variable come from? A: Maybe that's supplied by the 'loadDataAsync()' function.
              • Is 'done()' a standard function? Or is it a fake function, like 'fake_variable_name' is a fake variable name?
          • transition-mode - The transition-mode param attribute allows you to specify how the transition between two dynamic components should be executed.
        • Misc
          • Components and v-for - You can directly use v-for on the custom component, but in order to pass the iterated data into the component, use props.
            • I don't understand what is meant by "automatically injecting item into the component".
          • Authoring Reusable Components - When authoring components, it is good to keep in mind whether you intend to reuse this component somewhere else later. It is OK for one-off components to have some tight coupling with each other, but reusable components should define a clean public interface.
            • The API for a Vue.js component essentially comes in three parts - props, events and slots:
              • Props allow the external environment to feed data to the component;
              • Events allow the component to trigger actions in the external environment;
              • Slots allow the external environment to insert content into the component’s view structure.
          • Async Components - In large applications, we may need to divide the app into smaller chunks, and only load a component from the server when it is actually needed. To make that easier, Vue.js allows you to define your component as a factory function that asynchronously resolves your component definition.
            • Vue.js will only trigger the factory function when the component actually needs to be rendered, and will cache the result for future re-renders.
            • The factory function receives a resolve callback, which should be called when you have retrieved your component definition from the server. You can also call reject(reason) to indicate the load has failed. The setTimeout here is simply for demonstration; How to retrieve the component is entirely up to you. One recommended approach is to use async components together with Webpack’s code-splitting feature.
          • Assets Naming Convention - Vue.js actually supports naming your assets using camelCase or PascalCase, and automatically resolves them as kebab-case in templates (similar to the name conversion for props).
          • Recursive Component - A component can recursively invoke itself in its own template.
            • Make sure recursive invocation is conditional.
            • When you register a component globally using Vue.component(), the global ID is automatically set as the component’s name option. (...but what if there are multiple components with the same 'name'? Does the global ID need to be unique?)
          • Fragment Instance
            • It is recommended to always have a single root-level, plain element in templates.
              • Why: It ensures directives and attributes on the component element will be properly transferred, and also results in slightly better performance.
            • A fragment instance will still render the content correctly. However, it will not have a root node, and its $el will point to an “anchor node”, which is an empty Text node (or a Comment node in debug mode). Non-flow-control directives, non-prop attributes and transitions on the component element will be ignored,
          • Inline Template
            • When the inline-template special attribute is present on a child component, the component will use its inner content (in the parent component) as its template.
            • This makes the scope of your templates harder to reason about, and makes the component’s template compilation un-cachable. As a best practice, prefer defining templates inside the component using the template option.
      • Reactivity in Depth
      • Custom Directives
      • Custom Filters
      • Mixins
      • Plugins
      • Building Large-Scale Apps - The Vue.js core library is designed to be focused and flexible. The Vue.js ecosystem is a set of tools and libraries for building large SPAs with Vue. 
        • Modularization - For large projects it’s necessary to utilize a modularized build system to better organize your code. The recommended approach of doing so is by writing your source code in CommonJS or ES6 modules and bundle them using Webpack or Browserify.
          • If you’ve never used them before, I highly recommend going through a few tutorials to get familiar with the concept of module bundlers.
        • Single File Components
          • You can build single-file Vue components with Webpack + vue-loader or Browserify + vueify. 
          • Browserify can be easier to setup in scenarios where you don’t need the advanced features that Webpack offers.
          • The fastest way to get up and running with a pre-configured build setup is using the official vue-cli.
        • Routing - For Single Page Applications, it is recommended to use the official vue-router library.
        • Communication with Server - The vue-resource plugin provides an easy way to work with RESTful APIs. You can also use any Ajax library you like, e.g. $.ajax or SuperAgent. Vue.js also plays nicely with no-backend services such as Firebase, Parse and Hoodie.
        • State Management
          • In large applications, state management often becomes complex due to multiple pieces of state scattered across many components and the interactions between them. It is often overlooked that the source of truth in Vue.js applications is the raw data object - a Vue instance simply proxies access to it. Therefore, if you have a piece of state that should be shared by multiple instances, you should avoid duplicating it. Instead, share it by identity.
          • If we enforce a convention where components are never allowed to directly mutate state that belongs to a store, but should instead dispatch events that notify the store to perform actions, we’ve essentially arrived at the Flux architecture.
          • Vuex is a Flux-inspired application architecture that is designed specifically for managing state inside large Vue.js applications.
        • Unit Testing
        • Deploying for Production
          • Webpack
          • Browserify
        • An App Example
      • Comparison with Other Frameworks


  • 2015.05.21 - Laracasts - Learning Vue.js 0.12
    • Matt and Naveed said this wasn't worth watching; it's too different from the current version of Vue.
  • 2015.10 - Laracasts - Learning Vue 1.0: Step By Step
    1. He shows a 'Hello World' example that demonstrates two-way binding.
  • 2015.10.25 - Vue.js: A (re)introduction
  • 2016.08.24 - Takuya Tejima - How to Build SPA with Vue Router 2.0
  • 2016.11 - Udemy - Learn by Doing: Vue JS 2.0 the Right Way
  • Undated
    • Udemy - Vue JS 2 - The Complete Guide (incl. Vuex)
      • If you're using single-file templates / components that are being compiled with webpack, you can use camel-case for the actual tag names. If you're not compiling it (i.e. you just have a Vue component in a Flask template), you're restricted to what the DOM allows, and it does not allow case-sensitive tag names.

        • Expand
          • Section 1 - Getting Started
          • Section 2 - Using Vue.js to Interact with the DOM
            • 18 - Passing your own arguments with events
              • To pass your own argument, just update the function call with the argument in parentheses, and add the parameter to the function definition.
                • Example:
                  • The template would read <button v-on:click="increase(2)">Click me</button>
                  • The function definition would read "increase: function(step) {"
              • To grab the default event argument while also passing your own, refer to the former as '$event' in the function call, and whatever you want (e.g. 'event') in the function definition. It doesn't seem to matter where in the list of parameters the 'event' parameter shows up, but he says that '$event' is the specific name you need to use in the function call.
            • 19 - Modifying an event - with event modifiers
              • Use .stop and .prevent
            • 22 - Using Two-Way Data Binding
              • Use v-model
            • 24 - An Alternative to Computed Properties: Watching for changes
              • Use this for asynchronous stuff.
          • Section 3 - Using Conditionals  and Rendering Lists
            • 36 - Using an alternative v-if syntax: If you want to have a v-if apply to multiple elements that are at the same level, and you don't want to wrap them in a div, you can group the elements in a '<template>' tag (which is part of HTML5), which won't show up in the final HTML, and put the v-if on that template tag.
            • 40 - Using an alternative v-for syntax: You can do the same thing with v-for as mentioned above for v-if, where you put it on a <template> tag in order to wrap multiple elements.
            • 43 - Keeping track of elements when using v-for - He explains that you sometimes want to assign a unique ':key' to the element when doing a v-for so that Vue will track the element itself and not just the position of the element. (I found this hard to understand). Basic takeaway: if you're encountering weird behavior with v-for, be aware that adding a :key may fix the issue.
          • Section 5 - Understanding the Vue.js Instance
            • General thoughts: I didn't learn much that I didn't already know. I've noted below the key things I thought were useful that I didn't already know.
            • 65 - Accessing the Vue instance from outside - You can access certain internals of the Vue instance (like the 'data' variables) from outside that instance by assigning the instance to a variable and then using dot notation. Example: "vm.variable_name".
            • 67 - A closer look at $el and $data
              • If you look at the Vue object in your console, you'll see that it has ceratin variables, among which are $data, $el, and $refs.
              • $el is how Vue.js keeps track of our template / HTML code.
              • $data is how Vue.js keeps track of our data. If you want, you can access the variables through this (i.e. vm.$data.variableName rather than vm.variableName).
              • If you Vue.js doesn't create its own internal / black-box world. It's normal JavaScript and you can access its internals.
            • 68 - Placing $refs and using them on your templates - He introduce 'this.$refs', which is just used to access particular HTML elements. Just be aware that if you use this method to make changes to parts of the DOM controlled by Vue, those changes will be overwritten when Vue rerenders its template. So $refs is much more useful for getting information from the DOM rather than setting it.
            • 73 - How Vue.js updates the DOM - He explains how the Virtual DOM is a layer between the Vue instance and the actual DOM which allows Vue to only update those parts of the DOM which have actually changed, rather than changing the DOM every time a variable in Vue is set (because it might get set to the same value).
            • 74 - The Vue.js instance lifecycle
            • 75 - The Vue.js instance lifecycle in practice
            • 76 - Module wrap-up
            • 77 - Module resources and useful links
          • Section 6 - Moving to a "Real" Development Workflow with Webpack and Vue CLI
            • Lecture 79 - Why do we need a Development Server?
              • Apparently it's desirable to code in ES6 and have it transpiled to ES5 "so it runs in the browser". I didn't know that.
              • Answer to why to use a dev server:
                • it allows us to test under more realistic circumstances
                • it allows us to serve only a subset of our assets at first
            • 80 - What does "Development Workflow" mean?
              • A: It's a process by which you transform your files before putting them on the server so that you can benefit from particular special features:
                1. Compile single-file template - He's going to dive deeper into this, but basically it makes the code smaller and faster.
                2. Case-insensitive component selectors
                3. Preprocessors - Examples: Compiling ES6 to ES5, compiling SASS to SCSS
                4. ...and still other things.
            • 81 - Using the Vue CLI to create Projects
              • We're not going to use Webpack with Vue-loader, but instead use the Vue CLI.
              • To install, use 'npm install -g vue-cli'
              • You can then choose from several 'Project Templates'
                1. 'simple'
                2. 'webpack-simple' ← This is the one we'll use in the course.
                3. 'webpack'
                4. 'browserify / browserify-simple' ← browserify is an alternative to webpack
            • 82 - Installing the Vue CLI and Creating a new Project
              1. Install the latest version of node
              2. Run 'npm install -g vue-cli'
              3. Run 'vue init webpack-simple name-of-the-project-folder'
              4. Enter the created folder and run 'npm install'
              5. Run 'npm run dev' to run the development server, which will automatically recompile everything and create a server that you can access from your browser.
            • 83 - An Overview over the Webpack Template Folder Structure ← This lecture was helpful.
              • A 'src' folder is created that contains our source code.
              • .babelrc sets up babel, which is a transpiler that lets us run ES6 code and transpile it to ES5.
              • index.html is the file that actually gets served.
              • He explains the '<script src="/dist/build.js"></script>' line in index.html.
                • We're using webpack to combine all of our Vue files and output a 'build.js' file in a generated 'dist' folder.
                • You won't see the 'dist' folder in development mode because it's done in-memory.
              • package.json lists all of the dependencies
                • they're split into production dependencies (under the 'dependencies' key) and development dependencies (under 'devDependencies')
                • the vue-loader dependency is what allows us to use single-file templates (.vue files)
              • webpack.config.js - This is the file that configures how all the JavaScript should get combined ('built').
                • Example tasks: transpiling, setting up the build process
            • 84 - Understanding ".vue" Files
              • The goal here, the reason for the .vue files, is to be able to split up our Vue code into multiple files and then have them combined into one big bundle to be sent to the client.
              • main.js - This is the first file that gets executed.
                • It has an 'el' which is the actual mounting point for the app. None of the other Vue files will have an 'el'.
                • It has a 'render: h => h(App)' line, where 'App' is a 'compiled template' (eg import App from 'App.vue'), which is a way to specify which template should be rendered in the specified 'el'.
              • App.vue - This is the Vue application.
              • He explains how 'single file templates' have a 'template' section, a 'script' section, and a 'style' section, they get put into the main.js, which puts the compiled template into the index.html.
            • 85 - Understanding the Object in the Vue File
              • "The key takeaway here is that this object (created by a .vue file) behaves like a Vue instance."
            • 86 - How to Build your App for Production
              • Run 'npm run build' - This will create the dist folder, build.js, and minify the code.
            • 87 - Module Wrap Up
              • For the rest of course he'll use the 'webpack-simple' template and split up the Vue code into .vue files.
            • 88 - More about ".vue" Files and the CLI (not really a lecture, just notes)
              • The webpack-simple template doesn't support local CSS or Sass files, because no CSS loader is set up.
            • 89 - Debugging VueJS Projects
              • The two main tools are Chrome DevTools and Vue DevTools.
          • Section 7 - An Introduction to Components
            • 90 - Module Introduction - "Components are used to swap different parts of the website in and out."
            • 91 - An Introduction to Components
              • He does a simple demo in JSFiddle.
              • Vue.component('desired-name-of-the-html-tag', { Vue component })
              • Make sure to use a prefix for the HTML tag name to not interfere with other tags. For example, use your company's name as a prefix.
              • Unlike the root Vue instance, the 'data' parameter needs to be a function that returns an object rather than an object itself.
                • The reason is that the component kind of extends Vue and its data object would interfere with Vue's.
            • 92 - Storing Data in Components with the Data Method ← This was interesting.
              • He explains why the 'data' property of a component needs to be a function by doing a simple demo in JSFiddle to show what would happen if it was a regular object instead (the way it is in the root Vue instance).
              • He creates an object outside of the Vue component, sets up two components, and has them refer to the same data object. When he clicks a button to change an item in the data within one of the components, it updates that item in both components. So apparently this is the behavior that using a function avoids.
            • 93 - Registering Components Locally and Globally
              • If you do Vue.component('template-tag', {Vue-looking object}), and you have two different Vue instances, and they each have a 'template-tag' in them, then that component will show up in both Vue instances. This is referred to as a 'globally-registered Vue component'.
              • If you wanted to change it so that both Vue instances still have the 'template-tag' but only one of them has the component, you can 'register the component locally'. Basically you assign the '{Vue-looking object}' to a variable instead of passing it to the Vue.component function, and then in the Vue instance definition for the Vue instance that you want to have access to that component, you add a 'components: {'template-tag': componentVariable}' section.
            • 94 - The "Root Component" in the App.vue File
              • He basically just switches back from the JSFiddle example (in the previous lecture) to his WebStorm IDE to show how the App.vue file is a component. It needs to have its 'data' property be a function. Because it's the root component it's used differently from other components (as described in an earlier lecture, it's mounted with the 'render' Vue property), but it's a component, not a Vue.js instance; the Vue.js instance is created in main.js.
            • 95 - Creating a Component
              • You can create a component by:
                1. Creating a new .vue file with the single-file template format (template/script/style).
                  1. Make sure there's one root element in the <template> section.
                2. In main.js:
                  1. Add a line that says 'import ComponentName from "./path/to/componentname.vue"
                  2. Add a line that says "Vue.component('desired-tag-name', ComponentName)"
                3. Wherever you want the component to show up, add a '<desired-tag-name></desired-tag-name>'
            • 96 - Using Components
              • The naming convention for components is CamelCase with the first word capitalized.
              • He shows how to do a local import of a component (importing a component into another component).
              • He does a v-for using his new component, which seemed like something I hadn't seen before.
            • Assignment 6: Time to Practice - Components
              • This is a very easy assignment, it's giving you some practice at breaking up a one-Vue-file app into several smaller components.
            • 97 - Moving to a Better Folder Structure
              • When you start to get a lot of component files, it usually makes sense to start using subdirectories.
              • For smaller projects you may just want a 'components' subdirectory.
              • For larger projects you may want to have a subdirectory for each of your major 'features' / parts of the app.
            • 98 - Alternative Folder Structures ← This is just a short doc introing the structure below.
              • - main.js
                - users/
                - - account/
                - - analytics/
                - shop
                - - main/
                - - checkout/

            • 99 - How to Name your Component Tags (Selectors)
              • Summary: He goes into a bunch of options (things you can do), but ultimately recommends that you have your components show up as <kabob-case> in your templates and in the form 'template-tag': ComponentObject in the "components" section.
              • If you're using single-file templates / components that are being compiled with webpack, you can use camel-case for the actual tag names. If you're not compiling it (i.e. you just have a Vue component in a Flask template), you're restricted to what the DOM allows, and it does not allow case-sensitive tag names.
              • If you're using ES6 you can just list the name of the component object in the "components" section without specifying it as a key-value pair, and ES6 will turn it into a key-value pair where the key is set to the same name as the object (so it'll be 'ExampleObject': ExampleObject).
              • He has his filenames without prefixes, but then adds prefixes when listing them in the 'components' property. The reason is that the prefix is only to prevent accidental conflicts. When naming the files you don't need to worry about those conflicts, so you can skip the prefix (which should improve readability).
            • 100 - Scoping Component Styles
              • Add 'scoped' to the 'style' tag in a component to make sure its styles don't become global.
              • He tries to explain what the 'Shadow DOM' is but I didn't understand him.
              • Vue mimics this Shadow DOM behavior to get the scoped CSS to stay tied to the proper parts of the DOM; it does this by adding custom attributes to those parts of the DOM that have scoped CSS applied to them.
              • The scoped CSS styles get put into the head section of the page, and those styles select based on those custom attributes that Vue has added.
              • Vue always adds the styles from a component to the header section of the page, even if the styles are empty.
            • 101 - Module Wrap Up - He briefly recaps the topics already covered and explains what's next.
          • Section 8 - Communicating between Components
            • 103 - Module Introduction - He just briefly explains that this section is about communication between components.
            • 104 - Communication Problems - He gives a motivating example: a parent component has two child components. He wants to click a button in the parent component and have it change a displayed value in one of the child components.
            • 105 - Using Props for Parent => Child Communication - He just gives a simple example of passing a single prop from the parent to the child. In this case it's a 'name' variable which changes some text.
              • Example:
                • Parent component:

                  Code Block
                  <template>
                      <div>
                          <child-component :exampleProp="exampleVariable"></child-component>
                      </div>
                  </template>
                  
                  import ChildComponent from './components/ChildComponent.vue'
                  
                  export default {
                      data: function() {
                          return {
                              exampleVariable: "asdf";
                          }
                      }
                      components: {
                          'child-component': ChildComponent
                      }
                  }


                • Child component:

                  Code Block
                  <template>
                      <div>
                          <p>{{ exampleProp }}</p>
                      </div>
                  </template>
                  
                  export default {
                      props: [
                          'exampleProp'
                      ]
                  }


            • 106 - Naming props - Case-sensitive names only work if you're using the single-file template, which is the preferred development method anyway.
            • 107 - Using props in the Child Component - You can access the values of props just like any other entry in the 'data' object. You can also modify them, but IIRC Cody said that's not a best-practice. (In Lecture 109 Max explains why: objects and arrays are passed by reference, and so you would end up having the child component making changes to the object which the parent component is also referencing, which could make it harder to reason about what was going on. And if it's not an object or array, then it will change the value in the child component but not the parent component).
            • 108 - Validating props - He explains how to specify the allowed type(s) of each prop, whether it is required or not, and what default value it should have, if any.
              • To validate props, the 'props' entry in your component's Vue code should be an object (as opposed to a list of strings).
              • To specify a single type: propName: Type
              • To specify multiple possible types: propName: [Type 1, Type 2]
              • The benefit of validation is that it makes debugging easier: you know what the problem is.
              • To specify that the prop is required: propName: { type: Type1, required: true }
              • To set a default value: propName: { type: String, default: 'example value' }
                • If the default value is an object or array, it should be a function which returns the object / array.
            • 109 - Using Custom Events for Child => Parent Communication 
              • Motivating example: he wants a button in the child component that will change the name in the parent component.
              • Important Note: If the prop is an object or array, it is being passed by reference, which means that if you're changing it in the child component, it will also change it in the parent component.
              • Sending the event: this.$emit('nameOfTheEventInTheParent', dataToPass)
              • Receiving the event in the parent: <child-component @nameOfTheEvent="variableToChange = $event">, where $event refers to the data that was passed ('dataToPass'). The variable assignment here is just an example, you could also call a function with the $event data.
            • 110 - Understanding Unidirectional Data Flow - Components can only communicate with their parent or children. Sibling components cannot communicate directly with each other.
            • 111 - Communicating with Callback Functions - An alternative to emitting an event from a child component to call a function in the parent component is to pass (as a prop) a function from the parent down to the child as a callback function, and then have the child component call that callback function. The function will have a reference to the parent component's 'this' object.
            • 112 - Communication between Sibling Components
              • There are two or three ways to communicate between sibling components.
              • Motivating example: There's a parent component which contains a 'User Details' child component and another 'Edit User' component. We want to edit the user's age in the "Edit" component and have it show up in the 'View User' component.
              1. The first approach is to have the child component which is changing the value of the variable emit an event to the parent, and then have the parent update its variable, and have that pass down to the other child component.
              2. The second approach is to use a callback function instead of emitting an event.
              3. The third approach is an event bus. This is helpful if you have lots of nested components, so for example, if the sibling components aren't direct siblings but are more like 5th-cousins-5-removed.
            • 113 - Using an Event Bus for Communication
              • In Angular 2 this is known as "Services".
              1. In your main.js file, write "export const eventBus = new Vue();"
                1. The name of the variable (e.g. eventBus) doesn't matter.
                2. Make sure this line of code is before you instantiate the main Vue instance.
              2. In the component that will be changing the variable:
                1. Write "import { eventBus } from '../main';"
                  1. The curly-braces is ES6 syntax for importing named exports.
                2. Write "eventBus.$emit('nameOfTheEvent', infoToPass)"
              3. In the component which should receive updates about the variable of interest, put an event listener in the 'created()' hook:
                1. Add a line to import the eventBus.
                2. In your created() function, add this listener:
                  1. eventBus.$on('nameOfTheEvent', (infoToPass) => { this.variableName = infoToPass.variable })
              • Managing state can get very complicated. To make this simpler we can use VueX.
              • For simple-to-medium-sized applications you can use the eventBus approach.
            • 114 - Centralizing Code in an Event Bus
              • An alternative to emitting an event on the eventBus is having the emit happen in a method in the eventBus, and to then have components call that method when they want to change the value of that variable.
              • The basic point he wants to make is that if you want to avoid duplicating code across different components which are interacting with state, you may be able to centralize that code in the eventBus and have components call methods on the eventBus instead.
            • Assignment 7: Time to Practice - Component Communication - His example video is worth rewatching. He uses an eventBus and doesn't worry about action-at-a-distance. I don't think that's the way Cody would have done it.
            • 115 - Wrap Up
          • Section 9 - Advanced Component Usage
            • 117 - Module Introduction - 'In this module I'm going to introduce some other features of components'
            • 118 - Setting up the Module Project
              • Motivating example: He has an app with a 'Quote.vue' component which displays a quote. He wants to be able to pass in a quote from a parent component.
            • 119 - Passing Content - The Suboptimal Solution
              • He shows how to pass a single quote as a prop, then asks: "What if we wanted to pass complicated HTML to the child component instead of just a single string?" That is the problem that 'slots' solves.
            • 120 - Passing Content with Slots
              • To use a slot you just put a '<slot></slot>' in the child component and then put the HTML you want to pass in the parent component's template between the child component's tags.
            • 121 - How Slot Content gets Compiled and Styled
              • Scoped styling in the child component will also apply to any HTML that is passed in via a slot.
              • Any Vue.js commands (v-if, v-for, {{ }}) that are applied to HTML to be passed to the child will be applied in the parent component before the HTML is passed to the child.
            • 122 - Using Multiple Slots (Named Slots)
              • If you want to have multiple different slots you need to name them.
              • In the child component, add a name="nameOfTheSlot" attribute to each slot.
              • In the parent component, add a slot="nameOfTheSlot" attribute to the topmost tag that should be sent to each slot.
            • 123 - Default Slots and Slot Defaults
              • If you have a named slot and an unnamed slot, any HTML in the parent component that is set to be slotted, but is within a slot that doesn't have a name, will be passed to the unnamed slot. In other words, an unnamed slot is the "default" slot.
              • If you put anything between the <slot> tags in the child component, that material will be treated as the "default slot content", and will be displayed if nothing is passed down from the parent for that slot.
            • 124 - A Summary on Slots
              • He gives an example use-case: suppose you have a slideshow-style page, where each 'slide' has its own HTML, but you want all of the slides to be framed by the same HTML.
            • 125 - Switching Multiple Components with Dynamic Components
              • If you want to be able to have multiple different components put into a given place, you can put a <component></component> tag there, give it an attribute :is="selectedComponent", and then set the data property "selectedComponent" to the name of whichever component should be put in that spot.
            • 126 - Understanding Dynamic Component Behavior
              • By default, when you use the <component> tag to switch between components, those components are destroyed as they are swapped out.
            • 127 - Keeping Dynamic Components Alive
              • To avoid having a component destroyed when it's swapped out, wrap it in <keep-alive></keep-alive> tags.
            • 128 - Dynamic Component Lifecycle Hooks
              • Instead of referring to the 'destroyed()' and 'created()' hooks for kept-alive components, you can use the 'activated()' and 'deactivated()' hooks.
            • Assignment 8: Time to Practice - Slots and Dynamic Components
              • This was a very easy exercise, it takes ~5-10 minutes.
            • 129 - Wrap Up
              • He gives a brief summary: We learned how to use slots and dynamic components.
          • Section 10 - Second Course Project - Wonderful Quotes
            • 131 - Module Introduction
              • What's to be built: A simple app where you can use a textarea to enter a new quote, that gets displayed on the same page. You can display a max of 10 quotes, and you can delete created quotes by clicking on them. A progress bar shows how many quotes you've created.
            • 132 - Setting up the Project
              • He thinks about how to break up the project into components: a header component, a 'new quote' component, an 'all quotes' component, and a 'single quote' component. I just had everything in one component.
            • 133 - Initializing the Application
              • He creates 'quotes' and 'maxQuotes' properties in the App.vue file, and he creates a 'components' folder with a 'Quote.vue' file and a 'QuoteGrid.vue' file.
            • 134 - Creating the Application Components
              • He fleshes out the QuoteGrid and Quote components.
              • He sets up the Quote component to have a slot for the actual text of the quote, which will be supplied by the QuoteGrid component. I wouldn't have thought to do it that way.
              • He uses a bunch of bootstrap classes that I wasn't aware of.
            • 135 - Passing Data with Props and Slots
              • He implements the passing of the quote array from App.vue to the QuoteGrid, and then the text of the quote from the array in QuoteGrid to the actual Quote component.
            • 136 - Allowing Users to Create Quotes with a NewQuote Component
              • He uses a bunch of boostrap styles. I had a lot of trouble trying to get my version to look right.
              • He wraps the textarea in <form> tags, which I didn't do.
              • He basically just fills out the <template> portion of the component, the 'quote' data property, but doesn't implement the 'createNew()' method.
            • 137 - Adding Quotes with Custom Events
              • He implements the 'createNew()' method in the 'NewQuote.vue' component.
                • He clears the textarea as soon as he emits the 'quoteAdded' event, which seems like it would clear it even if the user has reached the max number of quotes and will need to delete another one before saving this new one.
              • He then implements the 'newQuote()' method in App.vue which just pushes the quote onto the array.
            • 138 - Adding an Info Box
              • He just adds two divs in the App.vue (one nested in the other). The main difficulty here is knowing which Bootstrap classes to use. I only used one div and couldn't figure out how to use Bootstrap to get the text formatted the way he had it formatted (centered with the vertical padding).
            • 139 - Allowing for Quote Deletion
              • He uses '@click.native' on the <app-quote> component. Apparently the 'native' modifier is needed when putting an @click on a custom component.
              • He adds a 'deleteQuote()' method to the QuoteGrid.vue component which emits an event that App.vue listens for, and then implements a 'deleteQuote()' method in App.vue to actually remove the quote from the array.
            • 140 - Controlling Quotes with a Progress Bar
              • He puts the progress bar and the h3 in a 'Header.vue' component.
              • He passes the quoteCount and maxQuotes from App.vue to the Header.vue component.
              • He doesn't use a computed property for the percentage for the progress bar; he does it in-line.
            • Lecture 141 - Finishing Touches and State Management
              • He implements the limit on the number of quotes.
          • Section 11 - Handling User Input with Forms
            • 143 - Module Introduction
              • Overview of the module: how to fetch values from input fields, how to use different form controls like radio buttons and checkboxes, and how to build your own form control from a component.
            • 144 - A Basic <input> Form Binding
              • Motivating example: A 'File a Complaint' form.
              • For a basic text <input> field, just use v-model to bind the input's value to a data property.
              • Confusing: He seems to first suggest that v-model will not overwrite human-entered input with other data if it's changed somewhere else, but then he seems to suggest that it will overwrite that input.
            • 145 - Grouping Data and Pre-Populating Inputs
              • He just points out that you can group your data into a single object and then refer to it using the dot notation in the form (so, 'userData.email').
              • He also points out that you can pre-populate the form by setting the data property to some non-empty value.
            • 146 - Modifying User Input with Input Modifiers
              • v-model.lazy will set the input to not update on every keystroke, but instead only when you click out of the input.
              • He suggests this might be useful for validating passwords.
              • Other modifiers: '.trim' gets rid of whitespace and '.number' forces the value to convert to a number.
            • 147 - Binding <textarea> and Saving Line Breaks
              • You use v-model to bind data properties to textareas as well.
              • To output linebreaks on a paragraph tag set a style of 'white-space: pre'
            • 148 - Using Checkboxes and Saving Data in Arrays
              • To handle checkboxes, just add a v-model to each input which refers to an array that will contain the selected boxes, and Vue will do the rest of the work to hook up the checkboxes to the array.
            • 149 - Using Radio Buttons
              • To handle radio buttons, just add a v-model to each input which refers to a string variable which will contain the selected radio button, and Vue will do the work to hook up the radio buttons to the variable.
            • 150 - Handling Dropdowns with <select> and <option>
              • To add options to a dropdown dynamically, have an array in your instance which contains the different options, then use a v-for on an <option> tag.
              • To have a default value, you can use ':selected="item == 'desiredDefaultValue'"', but the more-typical way to do it is to set the value of the variable which will contain the selected value, which the v-model on the select tag will use to set the default (see next point).
              • Use v-model on the 'select' tag, and have a separate string variable which will contain the selected value.
            • 151 - What v-model does and How to Create a Custom Control
              • All v-model does is combine 1) a v-bind with 2) an @input listener which updates the value.
              • So, to create a custom control, we just need to implement those two pieces: the component needs to have a 'value' prop, and it needs to emit an 'input' event.
            • 152 - Creating a Custom Control (Input)
              • Motivating example: He has a control which is basically like a lightswitch, where you can click on one half or the other to turn it 'on' or 'off', except it's oriented horizontally and has some colors.
              • He creates a 'dataSwitched' data property in the parent component, then creates a 'value' prop in his component, then creates a 'switched()' method which emits the 'input' event.
            • 153 - Submitting a Form
              • He creates a button which has a @click listener.
              • He adds a 'prevent' modifier to the click listener so that the HTML element won't immediately submit the form to the server. This way we can first examine the submission on the client-side, and then, if it looks good, we can submit it to the server using our own Vue code.
              • He creates a 'Submitted' method which sets a boolean variable which shows the submitted values on the page. So he doesn't actually do any validation or do a POST request.
            • Assignment 9: Forms
              • This was a pretty easy assignment.
              • Things he did that I missed:
                • He set the class of the inputs to 'form-control' to get the styling to look nice with Bootstrap.
                • He set the 'type' of the submit button to 'submit'.
                • When combining the firstName and lastName fields into a single fullName variable, he splits the full name on the space in the middle, which was an edge case that I immediately thought of and which had me feeling confused about how I was supposed to proceed.
                • He doesn't use data properties to hold the first and last name in the custom component, which complicates how he checks for changes.
            • 154 - Wrap Up - He just lists the things we covered in this module, which you can find easily enough by reading the titles of the lectures.
          • Section 12 - Using and Creating Directives
            • 156 - Module Introduction
              • Directives are the 'v-for', 'v-if' things.
              • This module is mainly about how to create your own directive.
            • 157 - Understanding Directives
              • Directives generally start with 'v-'. Then comes the name of the directive.
              • He demos Vue's built-in 'v-text' and 'v-html' directives.
              • He demos creating a 'v-color' directive.
              • There are two options when creating a directive: a global directive and a local directive.
                • Global: In main.js, write "Vue.directive('name', {configuration});"
            • 158 - How Directives Work - Hook Functions
              • Directives have five hooks.
              • bind() - Executed as soon as the directive is attached.
              • inserted() - Executed as soon as the element is inserted in the parent node.
              • update() - Whenever the component is updated.
              • componentUpdated() - Executed once both the component and its children have been updated.
              • unbind() - Executed when the directive is removed.
              • bind and update are the most-often used.
            • 159 - Creating a Simple Directive
              • He created a bind() function in the Vue.directive configuration
              • He accesses the element's style with "el.style" (I think this is based on Vue's internal representation of each element?)
              • "el.style.background = 'green'"
              • He then adds "v-highlight" to the element in the component file (.vue file).
            • 160 - Passing Values to Custom Directives
              • All he does is switch the hard-coded 'green' to "binding.value" and then update the code in the component to say v-highlight="red".
            • 161 - Passing Arguments to Custom Directives
              • He updates his calling code to say v-highlight:background=etc., and in the directive code he adds a conditional: if (binding.arg == 'background')
            • 162 - Modifying a Custom Directive with Modifiers
              • Motivating example: He wants to add a '.delayed' modifier
              • He accesses the modifier in the directive's code with binding.modifiers['delayed']
              • He points out that you can chain modifiers.
            • 163 - Custom Directives - A Summary
              • He just summarizes the topics of the previous lectures and the next lectures. It's a 28-second lecture.
            • 164 - Registering Directives Locally
              • Add a 'directives' property to the component's Vue code.
              • You can specify the name as a string with kabob-case or without quotes if you use camel-case.
              • The value (in the directives' key-value pairs) is the configuration, just like with the global version.
            • 165 - Using Multiple Modifiers
              • He implements another modifier, which creates a blinking effect. This doesn't really cover any new Vue concepts.
            • Lecture 166 - Passing more Complex Values to Directives
              • He switches the attribute value in the HTML from a string ('red') to an object ({ mainColor: 'red', secondColor: 'blue', interval: 1000 }).
              • He accesses those properties in the directive with binding.value.propertyName, for example binding.value.mainColor.
            • Assignment 10: Time to Practice - Directives
            • 167 - Wrap Up
          • Section 13 - Improving your App with Filters and Mixins
            • 169 - Module Introduction
              • He's going to cover both filters and mixins in a single module because they're quick to go over.
              • They help you structure your application.
            • 170 - Creating a Local Filter
              • What a filter is: A thing you can put in the template to transform the way some Vue data is displayed to the user.
              • Simple Example: A filter that displays a string in all uppercase.
              • How to use: You can register it globally with Vue.filter('name', function) or locally with the 'filters' property.
              • Each locally-registered filter is a function which receives a value as an argument and returns the transformed value.
              • To use the filter, you write {{ variableName | filterName }} (ie using a pipe)
            • 171 - Global Filters and How to Chain Multiple Filters
              • You can register global filters with Vue.filter('name', function).
              • You can chain filters like this: {{ variableName | filterOne | filterTwo }}
            • 172 - An (often-times better) Alternative to Filters: Computed Properties
              • The problem with filters is that Vue can't tell when it should rerun the outputted value from the filter and when it should just keep the old value, so it has to rerun the filter every time the DOM is updated. So Vue 2 has limited filters relative to their use in Vue 1.
              • Computed properties are only recalculated if they need to be.
            • 173 - Understanding Mixins
              • Motivating example: He has a computed property that he uses in multiple components, and it ends up duplicating code to have the function that computes the property in both components.
              • Main idea: Mixins are basically like components but without the 'template' part. So it's when you want to reuse the 'script' part of a Vue component.
            • 174 - Creating and Using Mixins
              • Copy all of the stuff between the <script> tags that you want to reuse into a new .js file.
              • In the component(s) where you want to use the mixin, create a 'mixins' property, and add a line that says "import { mixinName } from './path/to/mixin'"
            • 175 - How Mixins get Merged
              • In the event of a conflict between a mixin and a component it is being imported into, the Vue component that imports a mixin will never have anything overwritten.
              • If both a mixin and a component have a lifecycle hook, the mixin hook will get executed first, and then the component's hook will get called.
            • 176 - Creating a Global Mixin (Special Case!)
              • A global mixin is added to every component in your app, and so you rarely want to do this.
              • To create a global mixin, add 'Vue.mixin({ })' in your main.js.
              • You generally use this with plugins, where the mixin will get contained to your plugin.
            • 177 - Mixins and Scope
              • Each component which uses a mixin gets a fresh copy of the objects it contains, so you don't need to worry about one component changing data that another depends on.
              • If you want multiple components to share state, consider using an event bus.
            • Assignment 11: Time to Practice - Filters & Mixins

              • This was quick and easy.
            • 178 - Wrap Up
              • He summarizes the main ideas I already summarized above.
            • 179 - Module Resources & Useful Links
          • Section 14 - Adding Animations and Transitions
            • 180 - Module Introduction
              • Animations help your users understand where in the application they should focus.
              • We'll cover how to animate single objects, the transition of two objects, and animating whole lists.
            • 181 - Understanding Transitions
              • If you want to animate the appearance or removal of a DOM element (like, if you're using v-if or v-show), you can do that with a <transition> tag.
            • 182 - Preparing Code to use Transitions
              • He sets up a button and a div, where the button makes the div appear or disappear via 'v-if'.
              • He then wraps the div in '<transition>' tags.
              • He notes that you can only have one element (as a top-level element?) between <transition> tags.
            • 183 - Setting Up a Transition
              • When doing an animation, Vue attaches classes to the DOM element, and by styling these classes you can alter the animation.
              • He points out that these animations depend on v-if and v-show; you can't use some kind of custom Javascript to make the element appear.
              • When the condition for 'v-if' or 'v-show' becomes true, it first attaches a class named "*-enter", where * is the name of your transition. After one frame, it attaches a "*-enter-active" class until the animation finishes.
              • When removing the element it works the same, except with "*-leave" and "*-leave-active".
              • The default class name is "v-enter".
            • 184 - Assigning CSS Classes for Transitions
              • You can either just mess with the default ".v-enter" class in the "<style>" section of your .vue file, or you can specify a "name" attribute for the transition and then mess with the ".name-enter" class.
              • The CSS properties you use are typically the "transition" property or the "animation" property.
            • 185 - Creating a "Fade" Transition with the CSS Transition Property
              • He adds an "opacity: 0" line to the "fade-enter" class, then with the "fade-enter-active" class he adds a "transition: opacity 1s" line.
              • Weirdly, when setting the "fade-leave" class's styling he says you don't need to specify the opacity, and when setting the "fade-leave-active" class's styling he sets both "transition: opacity 1s" and "opacity: 0", which is different from how he did it when styling the enter-classes. He says that '1' is the default value for the 'opacity' property.
            • 186 - Creating a "Slide" Transition with the CSS Animation Property
              • He introduces a bunch of new concepts
              • First he sets up some keyframes with the "@keyframes" CSS setting: "@keyframes slide-in { ... }" and another one for 'slide-out'.
              • Both slide-in and slide-out have a "from" and "to" keyframe, for example: "from { transform: translateY(20px) }"
              • The class names are set up in the same way as in the previous lecture, but this time he's going to use the "animation" CSS property.
              • He doesn't need to put anything in the 'slide-enter' CSS property because the keyframes take care of the starting position.
              • In the 'slide-enter-active' class he sets the 'animation' property to 'slide-in 1s ease-out forwards', where 'slide-in' refers to the keyframes he created, 'ease-out' is an available CSS easing function, and 'forwards' prevents the element from snapping back to its starting position after the animation finishes.
              • He demos the animation, but it doesn't fade out, it just pops in and out.
            • 187 - Mixing Transition and Animation Properties
              • The goal here is to both have the sliding effect and also the fading effect.
              • He uses both the 'transition' and 'animation' properties in this case but points out that you could achieve the same effect solely through the use of the 'animation' keyframes.
              • If you have both a transition and animation and they have different times over which they run, you can specify which one should be 'definitive' by setting the 'type' attribute on the <transition> tag to either 'animation' or 'transition'.
            • 188 - Animating v-if and v-show
              • This is a 30-second lecture, he just points out that everything he's done so far works with 'v-show' just as it does with 'v-if'.
            • 189 - Setting Up an Initial (on-load) Animation
              • If you want the animation to play when the page initially loads, add an 'appear' attribute to the <transition> tag.
              • The problem is that Attribute.css requires you to add the name of the desired
            • 190 - Using Different CSS Class Names
              • He introduces the 'Animate.css' library, and adds it to his index.html
              • Animate.css works by having you add certain classes to the element you want to animate.
              • The problem is that Vue uses the '*-enter' etc. classes to do animations.
              • To get Vue to notice the Animate.css classes, you get rid of the 'name' attribute and instead add an 'enter-class' (etc) attribute which is the class or classes you want applied.
                • Example: enter-active-class="animated bounce"
              • At the time he recorded the video, the 'appear' attribute didn't work with those custom classes.
            • 191 - Using Dynamic Names and Attributes
              • You can bind the transition type dynamically by adding a colon to the beginning of the 'name' property.
            • 192 - Transitioning between Multiple Elements (Theory)
              • 30-second lecture to introduce the motivating situation: You have two elements, and you want the first element to play an animation, and when that animation finishes, have the second element play its animation.
            • 193 - Transitioning between Multiple Elements (Practice)
              • He creates a transition that wraps two divs, where they alternate using v-if and v-else.
              • If I understood him correctly, he says that animations between elements won't work with v-show, only v-if.
              • On his first attempt the animations don't work, and he says the reason is that if you wrap two divs, the animation-listener-portion of Vue can't tell that the elements swapped, because it just swaps the content of the divs.
                • To fix this he adds a 'key="keyName"' to each div.
              • Then there's another problem: the incoming div shows up lower on the screen than the outgoing div, rather than being in the same place on the screen, and then jumps up when the outgoing div's animation finishes and it is removed from the DOM.
                • To fix this, he adds 'mode="out-in"' to the <transition> tag, which has the outgoing div's animation finish before animating the incoming div.
                • He says another way to fix this would be to set the div's position to 'absolute', so they'd overlap each other.
            • 194 - Listening to Transition Event Hooks
              • He lists the different hooks available: before-enter, enter, after-enter, enter-cancelled, etc.
            • 195 - Understanding JavaScript Animations
              • He stresses that you can use both the JavaScript hooks and the CSS animations.
              • He demos using the JavaScript hooks.
              • He starts by adding a button that adds or removes a div that contains a green square.
              • He adds the different '@' hook-attributes to the <transition> element.
              • If you don't have any CSS animations in your <transition> tag (eg if you're solely using the JavaScript hooks), Vue won't know when the transition ends, and so you need to call a "done()" function in the 'enter()' and 'leave()' functions to let Vue know that the transition has ended (explicitly specifying when the transition ends allows you to have the transition end when some asynchronous call has finished).
            • 196 - Excluding CSS from your Animation
              • If you add :css="false" to your <transition> tag, that will tell Vue to skip checking for CSS animations and solely use the JavaScript hooks, which can make it run faster.
            • 197 - Creating an Animation in JavaScript
              • 'enter()' and 'leave()' are the two hooks to use for the actual animation.
              • He gives an example of having a div grow in width when you click a button, and shrink in width when you click the button again.
              • He uses setInterval to have the changes happen over a period of time.
            • 198 - Animating Dynamic Components
              • He sets up a situation where clicking a button switches between a "success" message component and a "warning" message component.
            • 199 - Animating Lists with <transition-group>
              • Very brief video; he just says that '<transition-group>' is used for lists.
            • 200 - Using <transition-group> - Preparations
              • In this video he just sets up a v-for to display the numbers (1, 2, 3, etc.) in an array, and then 'addItem' and 'deleteItem' methods.
            • 201 - Using <transition-group> to Animate a List
              • <transition> is not rendered to the DOM, but <transition-group> renders a <span>. You can override this by setting 'tag="TAG"'.
              • Otherwise the <transition-group> tag is generally used just like the <transition> tag.
              • One difference is that you need to set a dynamic key which will be different for each item, so that Vue can tell which item to animate.
              • By default the items will pop in and out and the rest of the items will jump suddenly to make room for a new item or to collapse the area where an item was just removed. To have the other elements slide gradually, you can define a '.slide-move' class and set 'transition: transform 1s'.
              • To allow the items below a removed item to slide above it while it's still be removed, you need to set 'position: absolute' in the 'slide-leave-active' class.
            • 202 - Understanding the App
              • He demos his 'Super Quiz' app, where you need to solve a simple addition or subtraction problem, and when you click the correct answer the list of questions flips over to reveal a message that says 'Correct!'.
            • 203 - Creating the App
              • Here he explains how he created the 'Super Quiz' app up to (but not including) the point where it has animations.
            • 204 - Adding Animations
              • Here he explains how he added the animations. This was the only assignment I couldn't figure out. He uses keyframes and a bunch of options that I wasn't familiar with. I had tried Googling the issue but was led down the wrong path by the links I found.
            • 205 - Wrap Up
              • He just summarizes the topics covered in this module.
            • 206 - Module Resources & Useful Links
            • 207 - The Animated "Monster Slayer" App
              • This is just an attachment.
          • Section 15 - Connecting to Servers via Http - Using vue-resource
            • 208 - Module Introduction
              • In a lot of applications you need to talk to a server between page-serves.
              • You often want the retrieve new information via AJAX rather than having to load an entirely new webpage.
            • 209 - Accessing Http via vue-resource - Setup
              • Since Vue is regular JavaScript, you can use whatever AJAX library you want. For example, you can use JQuery.
              • He's going to show a package called 'vue-resource' that adds some nice features when doing AJAX requests.
              • You can install vue-resource with 'npm install vue-resource --save'.
              • To enable it, add this to your main.js:
                • import VueResource from 'vue-resource'
                  Vue.use(VueResource);
            • 210 - Creating an Application and Setting Up a Server (Firebase)
              • Firebase is a service that you can use for a mobile or web app.
              • Set up Firebase:
                • Click 'Create New Project'
                • Name the project, click 'Create Project'.
                • He's only going to show the 'Database' part of Firebase for this demo.
                • Go to Database → Rules, and set the '.read' and '.write' rules to 'true' to allow us to write to the database.
              • Set up the Vue project.
                • He sets up 'username' and 'email' inputs which use v-model to bind to two data properties, and @click listener on a submit button that runs a 'submit' function.
            • 211 - POSTing Data to a Server (Sending a POST Request)
              • Sending the request:
                • Grab the endpoint in Firebase from Database → Data.
                • Since we added Vue.use(VueResource) in the global scope, all of our components now have access to a 'this.$http' object.
                • The first argument of 'this.$http.post()' is the endpoint to post to.
                • You need to add 'data.json' to the end of the endpoint because Firebase requires it. The 'data' part can be named by you, but Firebase requires that you work with .json.
                  • Amazingly, you don't actually need to set up anything in Firebase to get that part working; you don't need to create a 'data' thing in Firebase. It'll just take whatever you give it and create an entry.
                • The second argument for a POST request is the data that you want to post.
              • Working with the response:
                • Vue-resource uses a 'promise' approach for requests.
                • So you can have 'this.$http.post(...).then(response => { do stuff }, error => { do stuff })
                • The response body from Firebase will be an ID to that data.
                • If you post multiple times, you'll create multiple different entries, each with their own ID.
            • 212 - GETting and Transforming Data (Sending a GET Request)
              • He adds a 'Get Data' button.
              • He sets up a v-for to display each user in a list of users that he will query from the db.
              • He sets up a 'this.$http.get(endpoint).then( response => { do stuff }'
              • Vue-resource gives us some useful functions to use to deal with the response: one of them is 'response.json()', which parses the response for us. [What we do in the v2 code is "response.data['itemName']".
              • He points out that just accessing response.json() won't work because it returns a promise, so what we actually need to do is:
                • this.$http.get(endpoint).then(response => { return response.json() }).then(data => { do stuff }).
              • He writes some code to turn the object he gets back from Firebase into a list so that it'll work with the v-for.
            • 213 - Configuring vue-resource Globally
              • He notes that it would be nice to avoid having to repeat the full URL for every request.
              • To do this, he goes to his global main.js and writes:
              • He then sets the endpoint to an empty string, but points out that you could add some subroute there and it would be appended to the global value.
              • You can also set the headers (like the content-type) via that options object.
            • 214 - Intercepting Requests
              • To set these up, add 'Vue.http.interceptors.push((request, next) => { do stuff })
              • 'next' is a callback function that indicates what should happen after the intercepting function finishes.
              • The interceptor he creates changes 'post' requests to 'put' requests.
              • At the end of doing stuff he calls 'next()', but never actually specifies what it does.
              • He then shows the effect this has in Firebase: 'put' requests overwrite past requests.
            • 215 - Intercepting Responses
              • To intercept the response, you put a function within the 'next()' call.
              • Just as a demo, he overrides the built-in response.json() method:
                • response.json = () => { return {messages: response.body} }
                • The effect of this is to make his 'v-for' code work again.
              • He notes that you can use 'if' statements to only modify the request/response in certain situations.
            • 216 - Where the "resource" in vue-resource Comes From ← This was new for me
              • 'resources' are a feature that vue-resource makes available which lets you make AJAX requests by calling functions.
              • To set this up, he does the following in App.vue:
                • He creates an empty 'resources' object as a data property.
                • In the created() hook, he writes:
                  • this.resource = this.$resource('data.json');
                • He then comments out his existing 'submit' function and replaces it with:
                  • this.resource.save({url parameters}, {data you want to post})
            • 217 - Creating Custom Resources
              • He demos being able to easily switch an endpoint, so that he can switch "this.resource.save({}, this.user)"
                to "this.resource.saveAlt(this.user)".
            • 218 - Resources vs "Normal" Http Requests
              • This is a 30 second video where he just points out that 'normal' http requests are fine, you don't need to use resources all the time, it's just an alternative.
            • 219 - Understanding Template URLs
              • He shows how to make the endpoint dynamic, where he lets the user specify the endpoint: "{node}.json"
              • He shows the docs for the URI Templates standard (which is something independent of Vue), and says that all of the things described there will work.
              • He passes the dynamic endpoint to the resource with this syntax:
                • this.resource.getData({node: this.node}), where 'this.node' is the endpoint, and 'node' is the variable he used when setting up the resource.
            • 220 - Wrap Up
              • He just summarizes the topics covered.
            • 221 - Module Resources & Useful Links
          • Section 16 - Routing in a VueJS Application
            • 222 - Module Introduction
              • Routing is what makes single-page applications possible(?)
              • He explains how a single-page application works: you have a single 'index.html' file which gets loaded at the root URL, and then the URL changes, but the page only loads / rerenders the parts of the screen/page that need to be changed to reflect whatever action the user has taken by clicking that link.
              • He reiterates the major difference here: previously we were dealing with individual pages, where different Vue.js instances needed to exist for each page, and now we're having Vue.js handle the entire web app.
            • 223 - Setting up the VueJS Router (vue-router)
              • He shows the basic structure of the project he has attached which is ready to have routing added to it: it has an index.html with Bootstrap being imported, a bunch of (basically-empty) components that will be switched in and out with the router.
              • He then installs the Vue Router package with 'npm install --save vue-router'. He explains that the router is a separate package because some people might want to use Vue without the router.
            • 224 - Setting Up and Loading Routes
              • In main.js he writes "import VueRouter from 'vue-router';" and then "Vue.use(VueRouter);".
              • He says that you can specify your routes in another file and import that file into the main.js file.
              • He emphasizes that you need to register all of your routes with the root Vue instance for them to work.
              • He creates a separate file for the routes, calls it 'routes.js', and fills it with "export const routes = [ route objects go here ];"
              • Each route object has:
                • a 'path' attribute which specifies the relative URL which 'triggers' that route.
                • a 'component' attribute which is the imported component that should be loaded.
              • For the sake of demonstrating switching routes, he adds a second route for a 'Home' component.
              • He goes back to main.js and adds a line that imports the routes.js file: "import { routes } from './routes';". He explains that the curly-braces are necessary because he named the object to be exported.
              • He then adds a line in main.js: "const router = new VueRouter({ routes });
              • He then adds the created router object to the Vue instance by just adding a line which says 'router,'.
              • He then explains we need to tell the Vue instance where to load these components that are being loaded via the router. We do this with the <router-view> tag. He adds this tag pair to the App.vue file.
              • He points out the hash in the URL, explains that this is the way VueRouter handles routes, and says he'll go into it further in the next video.
            • 225 - Understanding Routing Modes (Hash vs History)
              • He explains that the hash is used to allow client-side JavaScript to intercept the request.
              • He says it would be nicer to not have the hash when creating an SPA, and then explains how to do it: set up your server to always return the index.html file, even when there's a 404. The Vue build.js will then get run, the URL will get parsed, and Vue will take over.
                • [Note from NW: Wouldn't this require two back-and-forths between the client and server? And wouldn't returning index.html each time require rerendering everything?]
                  • 2018.02.16 - In the next video he explains that using the <router-link> tags is how you have the app skip the request to the server.
              • To tell VueRouter that this is the desired mode, add a "mode: 'history'" line to your VueRouter configuration.
            • 226 - Navigating with Router Links
              • He copies some Bootstrap example code for buttons.
              • He explains that he doesn't want to use the href="" attribute for the link tags because that would send a request to the server, and it would be better if our app could handle the change without doing that.
              • He gets rid of the <a> tags and replaces them with <rounter-link> tags. He explains that the tags will be rendered as <a> tags but will have some special behavior.
              • The <router-link> tag determines where it will link to via a 'to' attribute which can either be a relative path (relative to the current URL) or with a leading-forward-slash, which will make the path relative to the domain (and not to the current URL, if the current URL is not the domain).
              • He imports the new 'Header.vue' component into the main Vue file and then demonstrates that it all works.
            • 227 - Where am I? - Styling Active Links
              • He demos a few different features of the <router-link> tag:
                • You can set the router-link to any tag that you want. He shows an example where Bootstrap uses <li> with an inner <a>. and shows that router-link can replace the <li> tags and then have empty <a> tags within (to satisfy Bootstrap's CSS selectors?).
                • You can specify what the 'link active' class should be.
                  • He shows an example where Bootstrap is looking for an 'active' class to style certain links, but router-link uses a 'router-link-active' class by default, which won't get noticed by Bootstrap. He's able to switch that active class to 'active' instead.
                  • You can specify an 'exact' attribute to make sure that a link is only shows as 'active' if that exact URL is present, rather than even if the URL shows up as a base of the current URL.
            • 228 - Navigating from Code (Imperative Navigation)
              • To navigate the router from your JavaScript code, use this.$router.push(stringRouteToGoTo);
                • He didn't need to import anything in his component to make 'this.$router' work. I guess it just automatically works because you attach it to the root Vue instance.
              • 'push' refers to pushing the new route onto the stack of visited routes, so that the 'Back' and 'Forward' buttons in the browser work properly.
              • push() can also take an object as an argument, he'll explain the benefits of that later.
            • 229 - Setting Up Route Parameters
              • To pass a dynamic segment in your path (e.g. '10' in  '/user/10') you append a colon and add a variable name (e.g. 'user/:id') when setting up your routes.
                • This is just how it works in Flask.
            • 230 - Fetching and Using Route Parameters
              • To access the dynamic parameter (e.g. '10' in 'user/10'), use this.$route.params.variableName
                • So in his example it's this.$route.params.id
              • Note that it's this.$route, not this.$router.
            • 231 - Reacting to Changes in Route Parameters
              • If a particular component is loaded and the path changes, but the same component would be loaded in the new path, the component isn't reloaded.
                • The example he gives is going from 'user/1' to 'user/2'. He has already assigned an 'id' variable in his data() section to the value of this.$route.params.id, and that assignment only happened the first time the component was loaded.
              • The solution is to set up a watcher for the change of these dynamic parameters and update the necessary parts of your components.
                • He watches '$route', so $route: function(toRoute, fromRoute) { etc. }
            • 232 - vue-router 2.2: Extract Route Params via "props"
              • It isn't a video, just a note: 
              • As of vue-router version 2.2, you can also bind your route params to props of the target components. This eliminates the need of watching $route .

                There are three ways of using this feature, check this official example to learn more: https://github.com/vuejs/vue-router/tree/dev/examples/route-props

                You can basically either pass a static value, bind a dynamic value to props or use a function to also convert your dynamic value.

            • 233 - Setting Up Child Routes (Nested Routes)
              • To set up subroutes, add a "children: [ ]" key-value pair to the route configuration. 
                • Each child route will have the same structure as the parent component (it'll be an object with a 'path' key and a 'component' key).
              • You can actually nest routes even if the URLs are different (i.e. even if the child route's URL doesn't contain the parent route's URL).
              • Nested routes aren't loaded in the root <router-view> tag, but rather in a <router-view> tag that you'll need to put in the parent component.
            • 234 - Navigating to Nested Routes
              • He just uses a <router-link> tag that has a "to" attribute that's set to the relative URL of the child component (so in his case, '/users/1', etc.).
            • 235 - Making Router Links more Dynamic
              • All he does is show that you can switch the static to attribute to the dynamic :to (with a colon in front), so that he can do :to="'/user' + $route.params.id + '/edit'"
            • 236 - A Better Way of Creating Links - With Named Routes
              • He shows an alternative way of filling out the :to field so that you don't need to use string concatenation. Basically you add a key-value pair to the route configuration where the key is name and the value is a string that you want to be the name, and then in the <router-link> you switch the syntax to :to="{ name: 'nameOfTheRoute', params: { id: $route.params.id } }" which is apparently easier.
              • He does say at some point that this is better when the URL is longer, so that makes sense to me.
              • Another advantage I could see of doing it this way is that changing the URLs would seem to be easier.
              • He also shows that you can use the same syntax when using this.$router.push() in your Vue code.
                • Ex: this.$router.push({ name: 'home' });
            • 237 - Using Query Parameters
              • He explains what query parameters are: they're the key-value pairs you see in URLs after the question mark.
                • Ex: www.example.com/login?next=app&something=100
              • He then shows how to add query parameters to a router URL using the object syntax for constructing the URL:
                • :to="{ name: 'userEdit', (...) query: { locale: 'en', q: 100 } }"
              • To access the query params, you use this.$route.query.paramName
              • He points out that just as with the normal URL parameters, you may need to set up watchers to watch for changes in the query parameters, depending on how your app works.
            • 238 - Multiple Router Views (Named Router Views)
              • You can use multiple router views within a single component.
              • To do this, add a name='routerViewName' attribute to the router-views, or leave it off of one that you want to serve as the 'default' router-view.
              • Then in your routes configuration, you'll replace the component: ComponentName key-value pair with a components: { 'router-view-name': ComponentName } key-value pair. The default router-view uses the special name default.
              • This seems like it could be useful for Rhymecraft.
            • 239 - Redirecting
              • To redirect when the user goes to a particular URL, use the following route set-up:
                • { path: '/redirect-me', redirect: '/user' }
                  • So basically you're just adding that redirect key-value pair.
                  • The value for redirect can also be an object with a name key like we saw earlier.
            • 240 - Setting Up "Catch All" Routes / Wildcards
              • Set up this route in your configuration.
                • { path: '*', redirect: '/' }
                  • So, just use an asterisk.
            • 241 - Animating Route Transitions
              • To animate route transitions, wrap the <router-view> tag pair with a <transition> tag pair, and set the options for the transition as the attributes for the opening tag.
            • 242 - Passing the Hash Fragment
              • To pass a hash fragment (like for an anchor tag), add a hash key-value pair to the :to link object.
              • The value for the hash key must apparently include the hash symbol, strangely enough.
                • So it's like hash: '#data'
              • At this point the link object is getting long, so he moves it from the template into a data variable.
            • 243 - Controlling the Scroll Behavior
              • Go to the VueRouter initialization and add a scrollBehavior option.
              • There's a savedPosition parameter for the scrollBehavior function which saves the position so that if a user clicks the 'Back' button in their browser, you can return them to the place on the page where they were scrolled to.
            • 244 - Protecting Routes with Guards
              • He explains that sometimes we may want to control if a user can enter a route and whether they should be able to leave the route.
              • He doesn't explain how to do it, but instead just sets up the example situation. The next videos explain how to implement it.
            • 245 - Using the "beforeEnter" Guard
              • There are three ways to check.
              • First way: set up a global check.
                • In main.js, set up a router.beforeEach(); method.
                • Be aware that the beforeEach function gets executed a lot, so it may affect the performance of your app.
              • Second way: in your routes config, add a beforeEnter key-value pair to the configuration for the particular route you want to run this check for.
              • Third way: in the actual component you want to do this check for, add a beforeRouteEnter function.
              • In all three methods, you must call next() to allow the user to continue.
              • In all three methods, you don't have access to the component data because it hasn't been loaded yet.
                • This may seem most unintuitive for the third method, since the code is in the component's Vue code where you normally would have access to the component's variables.
            • 246 - Using the "beforeLeave" Guard
              • There is only one way to check if a user may navigate away from a component, and that is with the beforeRouteLeave() component method.
              • In this case you do have access to the component's data, as would be expected.
              • This is useful for preventing users from accidentally navigating away if they have unsaved data.
            • 247 - Loading Routes Lazily
              • He shows how to defer the downloading of code for a particular component (or group of components) until they're accessed.
              • Each time you use this special syntax to replace the import statement in your main.js, Webpack will create a separate bundle for just that component.
              • You can also group components into a separate bundle.
            • 248 - Wrap Up
              • Nothing of substance.
            • 249 - Module Resources & Useful Links
          • Section 17 - Better State Management with Vuex
            • 250 - Module introduction
              • He points out that we've already learned a little about state management with props, emitting events, and using an event bus.
              • He says that this new method is good for bigger applications where those previous methods may not be sufficient.
            • 251 - Why a different state management may be needed
              • He introduces an example application where a grandchild component needs to communicate with its uncle/aunt component.
              • The problem with passing data from child to parent is that it's really complicated: you need to pass the data from the granchild to its parent, and then from its parent to its grandparent, and then from the grandparent to the uncle/aunt.
              • The problems with using an event bus are that:
                1. The event bus will quickly get crowded.
                2. Changes are hard to track.
            • 252 - Understanding 'centralized state'
              • There is a central store where the application's shared state is stored.
            • 253 - Using the centalized state
              • A common way to use Vuex is to have a store/ folderwithin your src directory, at the same level as your components/ folder.
              • Within the store folder he creats a store.js file.
              • He says he links to an article that describes different ways of setting up your file/folder system.
              • He does npm install ---save vuex to install Vuex.
              • In store.js he:
                • imports Vue and Vuex
                  • import Vue from 'vue';
                    import Vuex from 'vuex';
                • Sets up Vue to use Vuex.
                  • Vue.use(Vuex);
                • He configures the store.
                  • export const store = new Vuex.Store({
                        state: {
                            counter: 0
                        }
                    });
              • In main.js he then:
                • Imports the store object.
                  • import { store } from './store/store.js';
                • Adds a store key / value pair to the root Vue instance, like with the router.
                  • store: store,
              • You can now read and write to the store from within a component by accessing this.$store.state.variableName
              • He reiterates that the dollar sign in front of the variable is a way for Vue.js to say "this is a special variable created by Vue.js".
            • 254 - Why a centralized state alone won't fix it
              • He says that the problem is that if you have several active components which each use the same piece of data, and each process that data in the same way, you can end up with computationally-expensive duplication of work.
            • 255 - Understanding getters
              • He says that "getters" allow us to solve the problem he brought up in the previous video: you can have the data from the central state processed a single time, within the getter, and then accessed in its processed form by multiple components.
            • 256 - Using getters
              • getters go in the initialization of your Vuex.Store, same with the state.
              • Unlike state variables, getters are functions. They're passed the state automatically by Vuex as an argument.
              • To access the getter from a component, you use this.$store.getters.getterName
                • You don't include the parens at the end, even though it's a function.
              • NW: One question I'm left with is, is that getter being rerun for each component? Or is a getter run only once per 'tick' (or whatever you call it when the Vue instance updates).
              • NW: After having set up Rhymecraft with Vuex, I've realized that the advantage of having a getter for a state variable is that it lets you use the convenient "mapGetters" function in your components, so that you can write this.variableName in your components instead of needing to write this.$store.state.variableName everywhere.
            • 257 - Mapping getters to properties
              • If you're using a bunch of getters in a component, having a different computed property for each one can start to take up a lot of space.
              • To shorten the syntax for including them, we can use a helper from Vuex called mapGetters
              • In your component, above the export default { line, you add import {mapGetters} from 'vuex';
              • In your computed properties, you then add this:
                • ...mapGetters([ listOfStringsOfGetterNames ])
                • The three dots are an ES6 feature which will have the list of functions returned by mapGetters "unpacked" each as their own entry in the "computed" section.
            • 258 - Understanding mutations
              • He briefly explains that mutations are like the "setter" equivalent to "getters".
              • They're useful if you've got code in multiple components that makes the same kind of change to a particular state variable.
              • They're also useful for tracking what component updated a particular shared-state variable.
            • 259 - Using mutations
              • mutations is another key in the Vuex.Store initialization object (same as with state and getters).
              • Each getter is a function just like with the getters.
                • Example:

                  • Code Block
                    mutations: {
                        increment: state => {
                            state.counter++;
                        },
                        decrement: state => {
                            state.counter--;
                        }
                    }


              • To use the getter from a component, you run this.$store.commit('mutation-name')
              • You can do the same kind of short syntax for listing mutations within a component as with the getters, except the helper function is called mapMutations
                • Example:

                  • Code Block
                    <template>
                        <div>
                            <p @click="increment"></p>
                        </div>
                    </template>
                    
                    import { mapMutations } from 'vuex';
                    
                    export default {
                        methods: {
                            ...mapMutations([
                                'increment',
                                'mutation-2-name'
                            ])
                        }
                    }


            • 260 - Why mutations have to run synchronously
              • You can't run any asynchronous task within a mutation (such as reaching out to a server).
              • He says the reason is that the Vuex code isn't set up to be able to both allow asynchronous code within a mutation and also know for sure which mutation caused a particular change in a shared-state variable.
            • 261 - How actions improve mutations
              • Actions are like mutations in that you use them from components, but with an action you can have asynchronous code (like calls to APIs), and when the action is finished it will commit a mutation.
              • NW: You commit a mutation, and you dispatch an action.
            • 262 - Using actions
              • actions is another key in the Vuex.Store initialization object, just as with mutationsstate, and getters
              • Unlike getters and mutations which get a "state" object as an argument from Vuex, actions are passed a "context" object from Vuex.
              • The context object gives you access to features of the store that you will need, such as the commit() method and the getters.
                • Remember that the ''commit()" method is used specifically to commit mutations. It takes as an argument the name of the mutation, and an optional extra "payload" argument.
              • He shows something which I don't think I'd use often, which is that if a function is passed an object and you only need one property of that object, ES6 allows you to "deconstruct" the passed-in object and only have the property named.
                • Ex: increment: ({ commit }) => etc. will take the context object that's passed into the increment() function and just make the commit method available within the function. So you don't have to write context.commit().
                • Later: This is actually very helpful for when one action calls another action, because actions can only receive a single additional argument, so if you want to pass multiple things you need to use an object, which makes your action function definition not helpful because it just says you receive a single object instead of what the object has to contain. This feature lets you have the function defintion like this: exampleFunction: function({ param1, param2 }) {
                • Later: This is also helpful for decluttering your code if you have a lot of references to state variables.
              • He recommends that if you have even a single need for an action, that you commit all of your mutations via dispatching actions, even the synchronous ones, so that you establish a clear pattern. I guess the idea is to prevent bugs?
              • Vuex also has a mapActions helper function, just like mapMutations, to make it easy to list the actions that should be available within a component.
            • 263 - Mapping actions to methods
              • The way to dispatch an action within a component is this.$store.dispatch('actionName');
              • You can pass an argument to actions if you're using the mapActions short syntax for including actions.
                • He says later you can only pass a single argument.
              • The normal parameter name for an argument passed to an action is payload.
              • Mutations can also have a payload parameter.
              • You can't pass multiple arguments to actions / mutations.
            • 264 - A summary of Vuex
              • He runs through the major ideas he covered in the previous videos.
            • 265 - Two-way-binding (v-model) and Vuex
              • One way to do two-way binding is to create a method in your component that will call the action to dispatch a change to the variable you want to update the value of.
                • This method isn't as nice because it results in a lot of code, and the two halves of the two-way binding are separated (the computed property method and the method to call the action).
              • You can actually get v-model to work.
                • To do this, you need to use a rarely-used feature of computed properties, which is that you can set a get() method and a set() method for each computed property. In this case, the get() method would be the normal computed property function, and the set() method would contain the code that you'd normally have in the methods section.
            • 266 - Improving folder structures
              • He just says he's going to show us how to split up the Vuex initialization code into separate files.
              • He says there is at least one alternative set-up, but the way he's going to show us is used in all official examples.
              • He creates a modules/ folder within his store/ folder.
            • 267 - Modularizing the state management
              • The idea for the modules/ folder is to organize your state / getters / mutations / actions into groups based on the parts of your application they're used for.
              • The format for each JavaScript file within the modules/ folder is:
                • You have a const object for each Vuex property (state, getters, mutations, actions), where the format of the object is the same as what it would be in the Vuex initialization object.
                • At the bottom you add an export default { } object where the keys are the names of the Vuex properties (state, etc.) and the values are the objects you created above.
                  • He uses the ES6 shortcut of just listing the name once, which I think is confusing but w/e.
                • To merge the module into the stores.js Vuex initialization object, you just add a new modules key where the value is an object that has key-value pairs, where the key is the name of the module within the central store (I guess?) and the value is the actual object that has been imported from the module.
                  • NW: I'm not sure why they're key-value pairs and not a list.
            • 268 - Using separate files
            • 269 - Using namespaces to avoid naming problems
            • 270 - Auto-namespacing with Vuex
            • 271 - Wrap-up
            • 272 - Module resources and useful links
          • Section 18 - Final Project - The Stock Trader
            • ...
          • Section 19 - Deploying a VueJS Application
            • 299 - Module Introduction
              • Run 'npm run build' to generate the 'build.js' file.
            • 300 - Preparing for Deployment
              • If you're using one of these Project Templates, everything should be set up to be deployed.
              • webpack.config.js
                • 'new wepackDefinePlugin' - This will strip out warnings, reducing the filesize and making it more secure.
                • 'webpack.optimize.UglifyJsPlugin' - This minifies the javascript.
            • 301 - Deploying the App (Example: AWS S3) ← This was a really useful lecture.
              • A disclaimer: At the time of recording, AWS offered a free 12-month period which should cover what we're going to do, but make sure that's still true for you and make sure you don't enable anything extra.
              • Go to the AWS dashboard.
              • Click on 'S3'.
              • Click 'Create Bucket'.
                • Name it 'vuejs-deploy'.
                • Click 'Static Website Hosting'.
                  • Click 'Enable', then set the Index Document and Error Document to index.html.
                  • Click 'Save'.
                • Click 'Permissions'.
                  • Click 'Add bucket policy'.
                  • Google 'aws static webpage' to find the AWS docs, then scroll down and click 'Configure Your Buckets', then scroll down and select the code snippet it shows you.
                  • Replace 'example.com' with your bucket name.
                  • Click 'Save'.
                  • You can choose to enable logging.
              • Click on the link to the bucket you created.
                • Click 'Upload'.
                • Click 'Add Files'.
                • Choose the index.html file and then the build.js file.
                • Click 'Start Upload'.
                • Create a folder named 'dist' and move the build.js folder to that folder.
              • Click on the link to your bucket again.
                • Click 'Properties'.
                • Click on the 'Endpoint' link to be brought to your website.


      • rec'd by Naveed

...