从 Vue 1.x 迁移
FAQ
哇,非常长的一页!是否意味着 Vue2.0 已经完全不同了呢,是否需要从头学起呢,Vue1.0 的项目是不是没法迁移了?
非常开心地告诉你,并不是! 几乎90%的 API 和核心概念都没有变。因为本节包含了很多详尽的阐述以及许多迁移的例子,所以显得有点长。不用担心,你也不必从头到尾把本节读一遍!
怎么开始做项目迁移?
-
从运行 migration helper 这个工具开始。我们非常谨慎地把一个高级 Vue 开发工具简化并重新编译成了一个命令行工具。当这个工具发现了一个弃用的用法之后,就会给出通知和建议,并附上关于详细信息的链接。
-
然后,看看侧边栏给出的关于这一页的内容。如果你发现有的地方有影响,而该工具没有给出提示的,请检查并解决一下该项。
-
如果有测试的话,测试一边看看还有什么问题。如果没有测试的话,打开 app,随机翻一下,看一下有什么报错或者警告信息。
-
至此,你的 app 基本已经迁移完毕了。如果你有更多想了解的,可以阅读一下本节剩下的部分。
从1.0 迁移到2.0要花多长时间?
取决于以下几个方面:
-
要迁移的 app 的规模。(小到中型的基本上一天内就可以搞定)
-
为了耍耍 Vue2.0 的新功能分心了多少次。 😉 不是说你们,我们构建 Vue2.0 的时候经常发生这种事。
-
使用了哪些弃用的功能。基本上大部分弃用的功能可以通过 find-and-replace 来实现升级,但有一些还是要花点时间。如果你没有遵循最佳实践,那么 Vue2.0 会强迫你去遵循。这有利于项目的长期运行,但是也意味着重构(也许有些需要重构的东西已经过时)。
迁移到 Vue 2 ,我也需要更新 Vuex 和 Vue-Router ?
只有 Vue-Router 2 是可编译的,可以遵循 Vue-Router 迁移路径 来处理。幸运地是, 大多数应用不含有许多路由代码,所以迁移不用超过一小时。
对于 Vuex , 甚至 0.8 版本和 Vue 2 一起都是可以编译的,所以不必强制更新。 促使你立即更新的理由是 Vuex 2 有更先进的功能,比如模块和减少的样板文件。
模板
片段实例 移除
每个组件有且仅有一个根节点。不再支持片段实例,如果你有这样的模板:
<p>foo</p> <p>bar</p>
最好把它包裹到一个简单的容器里面去:
<div> <p>foo</p> <p>bar</p> </div>
升级方式
升级后,为你的 app 运行端对端测试 ,并关注关于多个根节点的console warnings。
生命周期钩子
beforeCompile
移除
用 created
钩子来代替。
升级方式
运行 migration helper 工具找到所有使用这个钩子的实例
compiled
替换
用 mounted
钩子来代替。
升级方式
运行 migration helper 工具找到所有使用这个钩子的实例
attached
移除
依赖其它钩子使用自定义的 dom 内部方法,例如:
attached: function () { doSomething() }
现在可以这样做:
mounted: function () { this.$nextTick(function () { doSomething() }) }
升级方式
运行 migration helper 工具找到所有使用这个钩子的实例
detached
移除
用自定义的 dom 内部的其他钩子代替,例如:
detached: function () { doSomething() }
可以用以下方式代替:
destroyed: function () { this.$nextTick(function () { doSomething() }) }
升级方式
运行 migration helper 工具找到所有使用这个钩子的实例
init
换名
用新的 beforeCreate
钩子代替,他们本质上是一样的。为了与其他生命周期的钩子命名保持一致性,所以重新命名了这个钩子。
升级方式
运行 migration helper 工具找到所有使用这个钩子的实例
ready
替换
使用新的 mounted
钩子代替,应该注意的是,通过使用 mounted
钩子,并不能保证该实例已经插入文档。所以还应该在钩子函数中包含 Vue.nextTick
/vm.$nextTick
例如:
mounted: function () { this.$nextTick(function () { // 保证 this.$el 已经插入文档 }) }
升级方式
运行 migration helper 工具找到所有使用这个钩子的实例
v-for
v-for
数组参数的顺序 改变
当含有 index
时,以前传递的参数顺序是:(index, value)
。现在变成了:(value, index)
,这样可以与js的新数组方法:forEach
,map
保持一致。
升级方式
运行 migration helper 来找到使用弃用参数顺序的实例。注意,该工具将不会标记以 position
或者 num
来命名 index 参数。
v-for
对象参数的顺序 改变
当包含 key
时,对象的参数顺序是 (key, value)
。现在改为了 (value, key)
,这样可以和通用的对象迭代器(比如 lodash 的迭代器)保持一致。
升级方式
运行 migration helper 来找到使用弃用参数顺序的实例。注意,该工具将不会标记以 name
或者 property
来命名 key 参数。
$index
and $key
移除
隐式申明的 $index
的 $key
两个变量在新版里面已经弃用了,取代的是在 v-for
中显式地申明。这可以使无经验的 Vue 开发者更好地理解代码,同样也可以使得在处理嵌套循环时更加清晰。
升级方式
运行 migration helper 来找到使用弃用变量的实例。如果有些没有找到,也可以参考控制台警告信息 比如 Uncaught ReferenceError: $index is not defined
track-by
替换
track-by
被 key
取代,和其他参数一样,如果没有 v-bind
或者:
前缀,它将被作为一个字符串。大多数情况下, 我们想要能够动态绑定完整的表达式,而不是一个 key。例如:
<div v-for="item in items" track-by="id">
现在应该写成:
<div v-for="item in items" v-bind:key="item.id">
升级方式
运行 migration helper 找到含 track-by
的实例。
v-for
排序值 改变
显然 v-for="number in 10"
将使得 number
从0到9迭代,现在变成了从1到10。
升级方式
以正则 /\w+ in \d+/
搜索整个代码,当出现在 v-for
里面时,检查一下,对你是否有影响。
Props
coerce
Prop的参数 移除
如果需要检查 prop 的值,创建一个内部的 computed 值,而不再在 props 内部去定义,例如:
props: { username: { type: String, coerce: function (value) { return value .toLowerCase() .replace(/\s+/, '-') } } }
现在应该写为:
props: { username: String, }, computed: { normalizedUsername: function () { return this.username .toLowerCase() .replace(/\s+/, '-') } }
这样有一些好处:
- 你可以对保持原始 prop 值的操作权限。
- 通过给予验证后的值一个不同的命名,强制开发者使用显式申明。
升级方式
运行 migration helper 工具找出包含 coerce
选项的实例。