去年vue尚未升級爲2.0點時候,建立了這個庫,而且寫了幾篇簡單的入門教程。發現也有一些朋友都拿這個collection來入門vue,在去年10月份vue升級2.0版本後,我一直沒時間來升級這個collection。如今終於有一整塊時間來作升級。藉助這幾個demo來感覺如何從vue1.x升級vue2.x。我新建了vue2.x分支,全部的升級改動都將提交到這個分支中。html
vue: ^1.0.0
to ^2.2.1
前端
vue-resource: ^0.7.4
to ^1.3.1
vue
vue-router: ^0.7.13
to 2.5.2
node
vuex: ^0.6.3
to 2.3.1
react
webpack: ^1.12.2
to 2.2.0
webpack
看完版本升級對比,感受我都是拿着「古董」寫的vue1.x版本的demo。vue全家桶+webpack所有有了重要的更新。前端生態就是這樣子,半年不去更新,世界都換了個樣子。git
本次升級所有基於vue-demo-collection
下的demo進行升級。必定還有升級中沒有接觸到的點,這裏不去深刻。github
webpack1.x和2.x最大的變化是module.loaders
變成了module.rules
web
如下是vue-cli
工具建立的vue1.x模版與vue2.x模版webpack配置文件module
代碼塊對比。vue-router
不妨本身嘗試一下,經過運行下面命令。找到工程目錄中的webpack.conf.js對比一下。
vue init webpack-simple@1.0 vue1.x
vue init webpack-simple vue2.x
對比發現:
modules.loaders
變爲modules.rules
vue
loaders變爲vue-loader
babel
loaders變爲babel-loader
module: { - loaders: [ + rules: [ { test: /\.vue$/, - loader: 'vue' + loader: 'vue-loader', + options: { + loaders: { + } + // other vue-loader options go here + } }, { test: /\.js$/, - loader: 'babel', + loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'url', query: { limit: 10000, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } } ] },
入口文件
從升級入口文件main.js
開始,Vue2.x的入口文件和Vue1.x相比,Vue實例帶有router和store選項。
router
配置參數注入路由,從而整個應用都有路由功能;
store
配置參數注入store到根實例,從而根組件下全部子組件均可以訪問store。
// 簡單的main.js import Vue from 'vue' import VueResource from 'vue-resource' import App from './App.vue' Vue.use(VueResource) new Vue({ el: '#app', render: h => h(App) })
// 帶有vue-router和vuex的main.js import Vue from 'vue' import VueRouter from 'vue-router' import routes from './routes' import App from './App.vue' import store from './vuex/store' // Vue.config.devtools = true Vue.use(VueRouter) const router = new VueRouter({ scrollBehavior: () => ({ y: 0 }), routes }) // Start up our app const app = new Vue({ router, store, ...App }) app.$mount("#root")
$Index
和$key
在vue2.x中已經被棄用,代替寫法爲:
<li v-for="(value, key, index) in objs" ></li>
vue2.2.0+
版本在組件使用v-for
指令到時候須要指定key
,這點和react
相似。
首先看兩張圖:
vuex1.0數據流閉環
vuex2.0數據流閉環
vuex中的store選項,從App
組件,移動到入口文件main.js
,在建立Vue實例的時候經過store對象提供給store
選項。
const app = new Vue({ store, ...App }) app.$mount("#root")
vue2.x中去掉了$remove
方法,使用splice
方法代替。
state.cart.splice(state.cart.indexOf(cartInfo), 1)
action中dispatch
變爲commit
,實踐中會用到ES6解構來簡化代碼。
actions: { increment ({ commit }) { commit('increment') } }
我對action中commit方法作了統一優化,用統一的函數處理commit。
import * as types from './mutation-types' const makeAction = (type) => { return ({ commit }, ...args) => commit(type, ...args) } export const changePrice = makeAction(types.CHANGE_PRICE) export const changeStyle = makeAction(types.CHANGE_STYLE) export const addItem = makeAction(types.ADD_ITEM) export const removeItem = makeAction(types.REMOVE_ITEM)
善用組件綁定的輔助函數
vuex2.x給開發者帶來另外一個福利,多了map*系列的輔助函數:
mapState - 建立組件的計算屬性返回 Vuex store 中的狀態 mapGetters - 建立組件的計算屬性返回 getter 的返回值。 mapActions - 建立組件方法分發 action。 mapMutations - 建立組件方法提交 mutation。
vue-router2.x中,路由初始化時,在建立Vue實例的時候須要傳入router配置向整個應用注入路由功能。
const app = new Vue({ router, ...App }) app.$mount("#root")
vue-router2.x中,router.map
替換爲router
實例裏的一個routes選項數組。
import Index from './components/Index.vue' import Cart from './components/Cart.vue' // Route config export default [ { path: '/', name: 'Home', component: Index }, { path: '/index', name: 'Index', component: Index }, { path: '/cart', name: 'Cart', component: Cart }, { path: '*', redirect: '/' } ]
v-link
指令已經被一個新的<router-link>
組件指令替代。
<router-link class="navbar-brand" :to="{ path: '/' }">Shopping Cart</router-link>