本篇文章記錄了完整的前端 Vue1.x 項目遷移至 Vue2.x 的步驟和遇到的問題。而且在遷移的過程也對Vue進行進一步學習。javascript
因爲項目後面但願用到餓了麼的 vue 組件,並且當前不少組件都是基於 Vue2.x 的,對於 Vue1.x 都已經再也不維護。html
Vue2.x 更加成熟,而且後面準備在移動端接入 weex ,而 weex 中也推薦使用 Vue2.x 進行開發。前端
綜上所述,下定決心開始對 Vue1.x 的項目進行遷移。vue
先介紹下原有項目的大體狀況。java
但願在遷移後,新功能的添加能夠徹底使用單頁面應用,而且配合用上 vuex 和網絡請求庫( axios )還有一些其餘的插件。react
現附上在遷移過程當中相關文檔地址:jquery
先安裝官方遷移工具vue-migration-helperios
npm install --global vue-migration-helper複製代碼
安裝完成後進入項目目錄,掃描項目中文件找出須要遷移的代碼位置。(並不能徹底找出,可是能夠解決大部分的遷移)git
個人遷移作法是掃描全局後,專一修改一類遷移問題,修改完後commit而且再次掃描確認該類問題已經解決。而後再解決下一類的問題。github
第一次掃描並輸出到文件中
vue-migration-helper >a.log複製代碼
輸出一看,WTF!!!500多個遷移點,網上人家遷移就幾十個遷移點。呵呵噠了。
首先提示的是修改 package.json 中的版本號,並從新 npm install
這個沒啥,我直接升到了最新的vue和vue-router版本
第一個解決的是 v-link
提示信息以下
找到相關文檔 cn.vuejs.org/v2/guide/mi…
文檔描述是把
<a v-link="'/about'">About</a>複製代碼
替換成
<router-link to="/about">About</router-link>複製代碼
But,項目中是這麼寫的
<button class="btn btn-default pull-right" v-link="{ path: '/'}">返回</button>複製代碼
查詢最新的 vue-router 文檔,可使用編程式導航,改爲以下
<button class="btn btn-default pull-right" @click="$router.push({ path: '/'})">返回</button>複製代碼
而後查找全部 v-link
類型問題一個個所有改過來,commit 提交。從新掃描一次。
$index
和 $key
的移除問題的提示是這樣的
主要是 Vue2.x 中移除了隱變量 $index
和 $key
,所有顯示聲明。修改例子以下
<tr v-for="clinic of clinicDatas">
<td>{{ $index+1 }}</td>
</tr>複製代碼
改成:
<tr v-for="(clinic, index) of clinicDatas">
<td>{{ index+1 }}</td>
</tr>複製代碼
回頭從新看了下 v-for
的文檔
默認命名 index
表明索引,key
表明遍歷對象的鍵值。
好比遍歷一個數組的時候,第二個參數是 index
索引
<ul id="example-2">
<li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li>
</ul>複製代碼
當遍歷對象時,第二個參數是 key
鍵
<div v-for="(value, key) in object">
{{ key }} : {{ value }}
</div>複製代碼
同時若是遍歷對象,還能夠有第三個參數表明索引
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</div>複製代碼
HTML 的計算插值移除 提示是這樣的
這個替換比較簡單,就是把 {{{}}}
所有替換爲 v-html
生命週期 ready 替換 提示是這樣的
要把生命週期鉤子函數 ready
替換爲如下:
mounted: function () {
this.$nextTick(function () {
// 代碼保證 this.$el 在 document 中
})
}複製代碼
在這裏我回頭看了下 nextTick
的具體概念:cn.vuejs.org/v2/guide/re…
意思就是當數據發生變化後 DOM 不會當即更新,而是會在一個更新週期時統一更新(感受就像 Android 的16ms 渲染刷新)。因此使用 nextTick
,是一個異步執行,意思是方法裏面的代碼會在下次 DOM 更新後執行。
Array-prototype-$remove 移除問題的提示:
數組的一個 remove
方法移除了,換成了 splice
方法。
vm.articleList.$remove(vm.temArticle)複製代碼
改爲
var index = vm.articleList.indexOf(vm.temArticle);
vm.articleList.splice(index, 1)複製代碼
v-el
和 v-ref
替換問題的提示:
直接全局將 v-el
和 v-ref
換成 ref
屬性內部的計算插值移除的提示:
屬性內部的計算插值已經不能再使用了:
<button class="btn btn-{{ size }}"></button>複製代碼
應該寫成行內表達式:
<button v-bind:class="'btn btn-' + size"></button>複製代碼
v-for
遍歷數組/對象時的參數順序變動問題的提示:
當包含 index
key
時,以前遍歷數組時的參數順序是 (index, value)
。如今是 (value, index)
, 目的爲了和 Javascript 原生中的順序保持一致。
router-go
改變 問題的提示是:
直接全局替換 router-go
爲 router-push
track-by
替換問題的提示是:
直接代碼全局替換 track-by
爲 :key
router
替換的提示是:
這個地方比較麻煩,要把全部路由定義都修改了。包括子路由的定義。原來的代碼是:
import Vue from 'vue'
import Router from 'vue-router'
...
Vue.use(Router)
var router = new Router()
router.map({//定義路由映射
'/': {
name: 'main',
component: Main,
subRoutes: {
'/': {
name: 'list',
component: List
},
'/list': {
name: 'list',
component: List
}
},
},
'/add/:assetId': {
name: 'add',
component: Add
}
});
router.start(Assets, '#app')複製代碼
修改成:
import Vue from 'vue'
import VueRouter from 'vue-router'
...
Vue.use(VueRouter)
var router = new VueRouter({
routes: [
{
path: '/',
name: 'main',
component: Main,
children: [
{
path: '/',
name: 'list',
component: List
},
{
path: '/list',
name: 'list',
component: List
}
]
},
{
path: '/add/:assetId',
name: 'add',
component: Add
}
]
})
const vm = new Vue({
router,
render: h => h(Assets)
}).$mount('#app')複製代碼
v-bind
的 once
和 sync
修飾符移除問題提示是:
這個問題將近 100 個地方,由於項目中定義了大量的組件。好比 翻頁組件、日期組件、上傳組件、地點組件等等。
在 Vue1.x 時能夠增長 sync
修飾符實現父組件和子組件的雙向綁定,可是到了 Vue2.x prop
只能單向傳遞,意思就是隻能父組件以 prop
方式將數據傳入子組件,可是子組件中不能夠對 prop
中的值進行修改,即沒法雙向綁定。
若是想要通知父組件進行數據修改須要定義組件事件,而後子組件中使用 $emit(eventName)
觸發事件,父組件中使用 $on(eventName)
監聽事件。
這個問題改的比較多,消耗了不少的時間。首先我要把涉及的組件從新設計,改爲反向事件觸發修改父組件屬性,而後父組件要監聽修改函數。
至此,基本上全部工具掃描出來的問題基本上改完了。但這還遠遠不夠,當我 npm run dev
時又報出來不少錯誤。基本上總結如下幾個問題。
問題報錯:
原來是個人 vue 文件中的 template
節點下有多個 div
節點。不知道爲何 Vue1.x 沒有報錯。所有統一爲一個 div
根節點。
個人一些方法定義是 delete
,這時報錯 delete
是 JavaScript 的關鍵字。我須要全部修改成另外一個名稱。
<modal title="系統提示" text="肯定刪除嗎?" id="deleteModal" :confirm-action="delete"></modal>複製代碼
這個多是我在遷移的時候一個標籤裏有了重複的 :class
, :click
屬性。本身刪除或者整合一下就行
編譯經過後,終於能夠跑起來了。這時候就須要每一個頁面進行測試,每一個操做進行測試。發現瞭如下幾個問題
content
address
組件都不能叫作這個名字了。要麼首字母改爲大寫。要麼換個名字。全部頁面跑過一遍,不少小細節慢慢調試修改,必定要細心再細心。(改的最多的仍是組件的部分)
最後500多個問題總共耗時2天多的時間才徹底跑通原有的項目。不過升級到 Vue2.x 後首先作的就是引入了餓了麼組件,感受方便不少,還有一些其餘插件在升級後均可以方便的使用。
注:以上只是我升級遷移過程遇到的問題。每一個項目不一樣會有不一樣的問題,建議以官方遷移文檔爲主。
更多文章關注個人公衆號