企鹅社区移动版Vue2.0升级手记

2,223 阅读7分钟

腾讯云技术社区-掘金主页持续为大家呈现云计算技术文章,欢迎大家关注!


刘小松:2010年加入腾讯,从事区域业务的应用开发,具备十余年的项目经验。在Vue的应用、腾讯新闻和微信的SPA开发有深度实践。

前言

企鹅社区移动版前端采用VUE 1.0开发。随着官方2.0的推出,前端界反响良好,由于项目本身在1.0的时候存在没有解决的问题,正好在2.0中得到解决,所以义无反顾地决定升级框架至2.0版本。

首先,官方推荐使用迁移工具,对当前项目做特性识别,并给出修改意见。个人觉得可以节省很多工作,可以快速找到差异点,并快速修改代码。下面简单介绍一下此次升级的过程,可为相似的项目提供参考。

第一步、安装迁移工具

官方文档参考:github.com/vuejs/vue-m…

本案例是在tlinux环境下运行的,若windows环境下,可能后续操作略有差异。

运行命令:npm install --global vue-migration-helper

尝试运行一下如下命令,检查是否安装成功:

vue-migration-helper

当运行上述命令提示vue-migration-helper: command not found时,你需要做一下ln操作。上图中已经告知程序安装的路径(下述命令中请替换你的文件路径),所以你可以执行以下操作:

cd /usr/local/bin/
ln -s /var/www/script/node-v4.4.7-linux-x64/bin/vue-migration-helper vue-migration-helper

第二步、借助迁移工具来评估迁移代码

进入项目文件目录,运行命令:

vue-migration-helper ./src/app/

正常的情况下就可以得到需要升级的代码清单:

由于清单数据量较大,不方便查看,可以调整一下命令将结果保存到文件:

vue-migration-helper ./src/app/ > /data/log/vue-update.log

下载文件后,可以通过文本工具查看:

第三步、升级代码

这个部分是升级工作中最花时间的部分。官方也有详细的参考说明,根据对应的点进行代码调整即可。

VUE:cn.vuejs.org/v2/guide/mi…

Vue Router:cn.vuejs.org/v2/guide/mi…

通过实践,我总结了几点在整个过程中遇到的难点和我的解决思路:

1、HTML插值变化,移除了{{{value}}}语法

在1.0中,需要格式化显示HTML内容时(用来处理换行转<br />及一些允许使用的特殊字符),我的做法是预先定义数据处理函数,然后使用filter定义为全局过滤器,直接对数据进行处理

Vue.filter('html', parseHtml);
{{{value | html}}}

而在2.0中,给出了新的方案

<div v-html="value"></div>

根据文档大意,在v-html指令中不支持过滤器。当然,我也尝试了一下

<div v-html="value | html"></div>

测试结果没有得到想要的,所以放弃了这种做法。要实现HTML的输出:

方法一:是在JS层预先做数据格式化,再赋值给变量(也可以用“计算属性”的方法)。优点是简单易用,直接调用v-html输出;缺点是在多种场景下调用的话,就会出现重复的代码。

方法二:封装公用组件,将数据处理放在组件内部,再将组件定义为全局组件。优点是可重复调用,统一处理方法,一处修复全局生效。缺点是在组件嵌套时,需要单独引入组件。

下面是htm.vue组件示例代码:

定义到全局组件:

调用示例:

2、生命周期变化,意味着来原的逻辑将会有大的调整

图:1.0版本

图:2.0版本

在1.0中使用ready钩子的地方需要替换,在2.0中可以使用mounted替代,可以参考官方文档

当然,在整个业务逻辑中,如果使用了上述其它钩子,也需要做调整。

3、VueRouter升级,导航钩子变化较大,带来的代码改造相对较多

详细的升级说明,请参考官方文档:cn.vuejs.org/v2/guide/mi…

在0.7中,当页面上有鉴权操作时,我会用到activate钩子,鉴权失败后可以友好终止用户的访问。升级后,虽然官方文档中建议使用beforeRouteEnter钩子替代,但缺点是无法访问this,需要做next回调来实现。

所以,我决定使用全局钩子来统一实现鉴权,实践证明能节省不少代码,在全局钩子中实现鉴权后,后续业务逻辑可以不再关注鉴权逻辑,代码更清爽了。

当然afterEach也非常好用,可以通过它来设置页面title等一些后续操作。

在0.7中,在加载数据环节,会用到data钩子,它专用于设置当前组件的数据,在2.0中,移除了此方法,确实带来了不便。文档建议使用watcher对$route做响应,然后调用定义的方法来处理。

实际项目中,获取组件数据的可以在template编译前执行,因此created钩子可以用来处理数据,代码升级的改造量最小。

通过watcher对$route做响应似乎有更重要的事情要做,看如下路由配置:

当路由带参数时,参数变化不会导致整个组件重新初始化,因此不会再执行created事件。在这种场景下,就必须使用watcher。

4、关于<keep-alive>组件的使用

在使用该组件时,需要考虑项目是否适用。下述情况不建议使用:

1)当数据交互相对较多的情况下,数据不会及时更新;

2)当页面需要带参数进行访问时,参数变化可能导致数据未更新;

3)需要及时鉴权的页面

我企鹅社区项目中,要让<keep-alive>生效,需要在顶层入口添加指令,模板如下:

<keep-alive>
<router-view></router-view>
</keep-alive>

其中<router-view>即是动态组件,此时会将整个项目的路由缓存起来(有些路由我是不希望被缓存的),这也是我感到<keep-alive>不够灵活的地方。

当然,事实也并非不可解决,Vue提供了两个专用方法可以场景下使用:

1)activated:在keep-alive组件激活时调用;

2)deactivated:在keep-alive 组件停用时调用;

因此在部分场景下,可以借助activated钩子来对数据进行处理,同时也借助watcher对$route做响应,可以实现带参数的页面动态起来。当然,这将带来巨大的代码改造量,需要仔细评估。

5、实现scrollBehavior遇到的坑

在router配置相对简单,仅需要添加一个方法即可:

配置后,并没有得到预想的效果。在测试过程中,打印savedPosition的值,始终为“0,0”,猜想scroll触发的事件没有正确获得滚动位置,于是查阅了VueRouter的实现代码

这里监控的是整个页面的滚动位置,而我们在实现上对body、#app挂载节点上做了height=100%的处理,导致滚动时并没有触发window的scroll。

于是,通过改造页面部局,将height=100%的定义去掉后,scrollBehavior终于生效了。但新的问题也随之而来,当body的高度没有超过window的高度时,会影响到页面上定义的浮层效果,所以优化无止境,还在探索中。

结束

此次升级原本计划3天时间,而最终花费的时间是1周。根据官方文档进行代码迁移后,仍然会有大量的报错,所以调试的过程也是深度理解Vue2.0变化的过程。

本文有一部分内容未提及,就是生产环境的升级,包括nodejs、webpack和Vue所依赖的库等系列工具,这部分虽然有一些变化,但都比较容易调整,这里就不多说了。

企鹅社区项目的移动版体验地址请扫二维码

相关阅读
Vue.js 实战总结
前端 fetch 通信
vue.js 初体验— Chrome 插件开发实录


此文已由作者授权腾讯云技术社区发布,转载请注明文章出处
原文链接:www.qcloud.com/community/a…
获取更多腾讯海量技术实践干货,欢迎大家前往腾讯云技术社区