本篇文章记录了完整的前端 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 后首先作的就是引入了饿了么组件,感受方便不少,还有一些其余插件在升级后均可以方便的使用。
注:以上只是我升级迁移过程遇到的问题。每一个项目不一样会有不一样的问题,建议以官方迁移文档为主。
更多文章关注个人公众号