Vue.js

From Colettapedia
Jump to navigation Jump to search

Vue.js

Files

index.html

  • has <div id="app" and script includes main.js

main.js

  • contains instantiation of Vue instance
import Vue from 'vue';
import App from './App.vue';
import store from './store';

new Vue( {
    store,
    render: h => h(App)
}).$mount( '#app' );

App.vue

  • top level component into which we compose other components
  • App-level arg array contains: const app = new Vue({
    • el: "#app" - el stands for element, maps back to the div in index.html
    • data
    • computed - contains methods. One-off computations in our dataset. Get access to the data using $this
    • filters - also contains methods that take arguments. Pass arguments to filter method inside the mustache using the pipe separator
    • methods - can take an argument
    • lifecycle methods
      • beforeCreate
      • mounted() fires when your app attaches to the DOM, a good time to fetch some data
      • beforeDestroy()

router/index.js

  • Entrypoint into Vue Router

store/index.js

  • Entrypoint into Vuex

Directives

  • directive inside HTML tags start with v-
  • v-bind:____="someDataStoreObj - bind keeps something up-to-date with some data store property
  • v-if="varName"
  • v-for:"i in datastoreobj"
  • v-on:click="someMethod" - binds a function to button
  • <input v-model="message"> - direct two-way binding between input and app state

Component

  • How you create a new HTML tag, you must register them
  • Template can only return one top level element, if you need to return two, wrap within a div.
  • computed properties of a component are just like regular data members
    • Can be declared methods, but call as if they were attributes.
  • Component scaffold has template, script, and style
  • export default {
    • props: ['id, 'age', 'weight] }
    • name = "component_name"
    • components: [ subcomponent1, subcomponent2 ]
  • <style scoped>

Vue Instance

Vuex

Cheat sheet

  • dispatch actions, commit mutations

Concepts

  • State management library
  • Extract shared state out of components and manage it in a global singleton
  • Use when you do a lot of passing data from one component to another through props.
  • When you don't want your data all over the place
  • Vuex stores are REACTIVE, meaning when vue components retrieves state from it, they will reactively and efficiently update the store's state changes.
  • You cannot directly mutate the store's state. The only way to change a store's state is by explicitly committing mutations. Can log every mutation, take state snapshots, or perform time travel debugging.
  • Modules - encapsulating/separating out logic for different components
  • E.g., whenever store.state.count changes, it will cause the computed property to re-evaluate, and trigger associated DOM updates.
  • By using Vue.use(Vuex) and passing the store augument to the root instance, any component can get at the store by calling this.$store

Flux pattern concepts

  • flux pattern concept created by Facebook
  • All you technically need is an event system
    • Unidirectional dataflow, because all actions go through the same dispatcher
    • All components will know when data has changed and con update appropriately
    1. All starts with an action
    2. Calls a dispatcher to propagate an event
    3. Puts the result into a store
    4. Store emits an event to tell components that are subscribed to it that the data has changed
    5. The views consume the data from the store
  • Many implementations. Redux is another example of Flux pattern but for React framework

Four types of entities in the modules

state

  • put data members in here as an object

getters

  • When you need to compute a derived state based on a store state.
    • like do a filter
  • all getters go in computed properties.
  • Getters are like computed properties for stores: will only re-evaluate when some of its dependencies have changed.
  • Get things out of the store with these methods, otherwise you will need a computed property in your component that pulls directly: this.$store.state.foo
  • getter methods take a single argument state
  • Can also pass arguments to getters by returning a function
    • getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id)}
  • Can use getters via this.$store.getters.doneTodos or mapGetters helper

mutations

  • always synchronous - you can't capture the "before" and "after" snapshots if mutations are asynchronous.
  • list out the different possible ways the state can change.
  • Vuex mutations are similar to events.
  • Each mutation has a string type and a handler.
  • Mutation handler methods takes one or two arguments, state, and optionally a payload which can be a scalar or an object.
  • YOU CANNOT DIRECTLY CALL A MUTATION HANDLER, instead invoke store.commit

actions

  • Similar to mutations except:
    • Instead of mutating the state, they commit the mutations
    • Contains arbitrary asynchronous operations.
  • Called from components to commit a mutation
  • Can be synchronous OR synchronous
  • Can do multiple mutations at once
  • All actions do is call the dispatcher with some parameters and an operation
  • Actions method take two arguments
    • context (similar to state object, which exposes the same set of properties/methods on the store instance)
      • Use ES2015 argument destructuring to pull a member out of an object so you don't have to keep using . to call a method on an object
    • payload
  • Can daisy chain, a.k.a "compose" actions
actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // wait for `actionA` to finish
    commit('gotOtherData', await getOtherData())
  }
}


Vocabulary

  • Dispatch actions versus commit mutations
  • const jokes = await fetch( 'jokes.json' )
  • Commit a mutation

Vuex helper methods

  • helper methods return objects
  • Use the elipsis ... "object spread operator" from ES2015 (Python equivalent is **) if we ever want to use helper methods in combination with other local methods.

mapState

  • import { mapState } from 'vuex'
  • FOUR ways to map store state to component state
    1. Arrow function: count: state => state.count
    2. Map a property to a string if you want to rename countAlias: 'count'
    3. Or just pass the string
    4. A normal function to mix local "this" state with store state: countPlusLocalState (state) {return state.count + this.localCount}

mapGetters

  • Put inside components computed properties

mapMutations

  • Put inside component's methods properties
  • Example: map `this.increment()` to `this.$store.commit('increment')`
    • methods: { ...mapMutations([ 'increment', 'incrementBy']) }

mapActions

  • Like mapMutations, put inside component's methods properties
  • Example: map `this.increment()` to `this.$store.dispatch('increment')`
    • methods: { ...mapActions([ 'increment', 'incrementBy']) }

Code

App.vue

const store = new Vuex.Store({

})

store/index.js

import Vuex from 'vuex';
import ModuleName from './modules/ModulName'

// Load Vuex
Vue.use( Vuex );

// Create store
export default new Vuex.store( {
    modules: {
        ModuleName
    }
}
);

Vue Router

  • Single Page App (SPA)

Basic Directions

  1. Use <router-link> and <router-view> tags inside your component
  2. Import route components
  3. Define routes and map components to routes
  4. Instantiate router instance and pass the routes to the constructor
  5. Inject the router to make the whole app router aware

Knobs and dials

  • Now you get this.$router and this.$route inside of the component
  • router-link automatically gets the .router-link-active class when target route is matched.

Dynamic Route Matching

  • Use dynamic segment in the route path
  • When a route is matched the value of the dynamic segment will be exposed as this.$route.params

Vue CLI

  1. npm install -g @vue/cli
  2. vue --version
  3. vue ui
  4. Create new project, include vuex and vue router components
  5. Run Project task 1: serve
  6. Run Project task 2 (build):

2018 Tech Stack