Download - Vue 2.0 + Vuex Router & Vuex at Vue.js
Vue 2.0+Vue Router & Vuex
Indie Inc. Co-founder & CTOTakuya Tejima
Who• Takuya Tejima @tejitak
• Co-founder & CTO at Indie Inc.• Server & Web Front-end, iOS Engineer
• DevMorning community founder• http://devmorning.connpass.com/
• Vue.js core team member
Vue.js MeetUp Tokyo!• 2016/5/31
• Vue.js Tokyo v-meetup="#1"
• http://vuejs-meetup.connpass.com/event/31139/
• Evan creator of Vue.js joined via Skype!
• He said “Vue.js is for everyone, not for a company”
What is Vue.js
Vue Component Example
<template> <div id="app"> <img src="./assets/logo.png"> <h1>\{{ msg }}</h1> </div></template>
<script>export default { data () { return { msg: 'Hello Vue 2.0!' } }}</script>
<style>body { font-family: Helvetica, sans-serif;}</style>
Example of App.vue with webpack https://github.com/vuejs-templates/webpack-simple-2.0
Vue.js 2.0
Our JavaScript framework is faster than React
improves initial rendering speed and memory consumption by up to 2-4x in most scenarios.http://www.infoworld.com/article/3063615/javascript/vuejs-lead-our-javascript-framework-is-faster-than-react.html
Vue 2.0 Features
• Fast!• Rendering layer is based on Snabbdom (a lightweight virtual-DOM
implementation) https://github.com/paldepind/snabbdom• Compiler & Runtime are now separated
• Reactive!• No need for shouldComponentUpdate / immutable
• Template ? JSX?• You can use both with original template & new render function
• Sever Side Rendering! (Streaming SSR)• NativeRendering• Compatibility with v1.0
Vue 2.0 API Changes
• Lots of APIs are deprecated https://github.com/vuejs/vue/issues/2873
• Filter! (e.g. <span v-text="message | reverse"></span>)• only available in text interpolations {{}}• no build-in filters
• vm.$dispatch -> Vuex event bus• vm.$appendTo -> Just use native DOM API• v-for $index & $key -> (value, index) in arr, (value, key) in
obj• etc.
Rendering Implementations
• https://speakerdeck.com/kazupon/next-vue-dot-js-2-dot-0
Vue Router
Popular Frameworks for SPA Implementation
• How to implement a SPA (Single-page Application)• Backbone, Ember, Riot, Angular + ui-router, Angular2,
React + React-Router (+ Redux), Vue.js + Vue-Router (+ Vuex)
• Important things to introduce• Does your app really need to be a SPA?
• For example, do you need partial rendering? • Choose framework depending on your app characteristics
What’s Vue-Router• Creating a SPA with Vue.js + vue-router is dead simple• Not only client-side routing (hash / history API), but also module based URL mapping
• Nested routes and sub components• Async load• etc.
• The following hooks are available• data, activate, deactivate, canActivate, canDeactivate, canReuse• NOTE The hooks will be changed to onEnter, onLeave, onChange in Vue-Router
v0.8.0• https://github.com/vuejs/vue-router/issues/321
Nested Routes and Sub Components & Hooks
Example URL change: /a/b/c -> /a/d/e
2. Validation phaseCheck if all current components can be activated / deactivated
3. Activation phaseDeactivate current components and activate new components with data hook
1. Reusability phaseCheck reusability
Code Examplemain.vue router.map({ '/about': { component: require('./components/about.vue') }, '/user/:userId': { component: require('./components/user/index.vue'), subRoutes: { 'profile/:something': { component: require('./components/user/profile.vue') } }, '*': { component: require('./components/not-found.vue') }, })
app.vue<template> <div> <p v-show="authenticating" style="color:red">Authenticating...</p> <h1>App Header</h1> <a v-link="{ path: '/about' }">about</a> <a v-link="{ path: '/user/1234/profile/what' }">user</a> <a v-link="{ path: '/mypage' }">mypage</a> <router-view class="view" transition="test" transition-mode="out-in" keep-alive></router-view> </div></template>
components/user/index.vue<template> <div> <h2>User yo</h2> <router-view></router-view> </div></template>
components/user/profile.vue
Authentication
router.beforeEach((transition) => { if (transition.to.path === '/mypage') { router.app.authenticating = true // check if the user is authenticated api.checkAuth().then(() => { router.app.authenticating = false // authentication success transition.next() }).catch(() => { router.app.authenticating = false // authentication failed transition.abort() }) } else { transition.next() } })
Example auth page implementation with global before hook
Is Vue-Router Enough?
• If your SPA with Vue-Router has complex component state structures, Vuex could be a solution
• Basically, more communications (e.g. dispatch & broadcast) between components leads to unreadable code
Vuex
Vuex• Official redux inspired flux framework for Vue.js
• Vuex is more fit for Vue.js with efficient reactive system such as data reactive rendering & components systems
Vuex• Features
• Store• basically a container that holds your application reactive states
• only way to change a store's state is by explicitly dispatching mutations • Mutation
• sync (can not be async)• split into modules with corresponding slice of the state
• Action• dispatch mutations• can be async
• Advantages• simple unidirectional flow (less side effects)• easy undo/redo - time travel• hot reloading• easy test
Vuex Flow Summary with Counter Example
Mutation Example• Mutation (a name and a handler) mutates states with synchronous functions
• Vuex store's state is made reactive by Vue• When we mutate the state, Vue components observing the state will update
automatically
import Vuex from 'vuex'
const store = new Vuex.Store({ state: { count: 1 }, mutations: { INCREMENT (state) { // mutate state state.count++ } }})
store.dispatch('INCREMENT')
• Must be called by dispatch in Action
What’s a Getter• A getter provides accessing way to store data from components
• Components are not allowed to directly mutate a state• It allows us to reuse computed methods (e.g. totals, averages) through a getter
- Getter Example// getters.jsexport function filteredMessages (state) { return state.messages.filter(message => message.threadID === state.currentThreadID)}
- Component<script> export default { vuex: { getters: { filteredMessages } } }</script>
<template> <div> <ul> <li v-for="msg in filteredMessages">{{mgs.title}}</li> </ul> </div></template>
NOTE the design may changed at Vuex 2.0https://github.com/vuejs/vuex/issues/236
Vuex Form Handlingv-model directly rewrites store data. This is not the Vuex way (throws an error in strict mode)The Vuex way with v-model - Set a getter value to form value - Dispatch action by UI event (e.g. onclick)
Template: <input :value="message" @input=“updateMessage”>JS: actions: { updateMessage: ({ dispatch }, e) => { dispatch('UPDATE_MESSAGE', e.target.value) } }
Dev Toolshttps://github.com/vuejs/vue-devtools
Vue-Router + Vuex
Vue-router-sync• Vue Router x Vuex
• Inject (sync) router states to Vuex states
• Components can access router data (path, params, query) through vuex getter in components router
• https://github.com/vuejs/vuex-router-sync
SPA with Awesome Vue Family
• If your application is not SPA just use Vue.js
• If your SPA …
• Needs mapping URL for components / partial rendering -> Vue Router
• Needs complex component state structure -> Vuex
• Needs both above -> Vuex + Vue Router + Vue Router Sync
Join Vue.js Community• Vuejs-jp Skack
• https://vuejs-jp-slackin.herokuapp.com/
• Translations
• Vex docs are working in progress
• https://github.com/vuejs/vuex/pull/240
Thanks