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

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

前言

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

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

第一步、安装迁移工具

官方文档参考:https://github.com/vuejs/vue-migration-helper

本案例是在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:https://cn.vuejs.org/v2/guide/migration.html

Vue Router:https://cn.vuejs.org/v2/guide/migration-vue-router.html

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

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升级,导航钩子变化较大,带来的代码改造相对较多

详细的升级说明,请参考官方文档:https://cn.vuejs.org/v2/guide/migration-vue-router.html

在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所依赖的库等系列工具,这部分虽然有一些变化,但都比较容易调整,这里就不多说了。

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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏静晴轩

Webpack 打包优化之速度篇

在前文 Webpack 打包优化之体积篇中,对如何减小 Webpack 打包体积,做了些探讨;当然,那些法子对于打包速度的提升,也是大有裨益。然而,打包速度之于...

3402
来自专栏IT技术精选文摘

如何利用配置中心规范构建PaaS服务配置

在上一篇文章中,我们以MQ和ACM为例,讨论了如何借助配置中心对消息进行限流管理的场景。在本文中,我们继续以该场景为例,讲述如何以规范的配置命名格式来进行限流设...

3548
来自专栏皮振伟的专栏

[virt][clock]steal time技术分析

前言: 在《clocksource的管理和虚拟化》中,大概分析了kvm clock,tsc,hpet等clock source。其中尤其是kvm clock计算...

3106
来自专栏Python疯子

Xcode里的Instruments工具:Leaks、Allocations、Time Profiler、Automation

显示如图,并按下键盘:command+R 运行app,此时手动操作app查看内存泄露

913
来自专栏北京马哥教育

高薪全栈工程师必备Linux 基础

Linux 几乎无处不在,不论是服务器构建,还是客户端开发,操作系统的基础技能对全栈来说都是必备的。 系统的选择 Linux发行版本可以大体分为两类,一类是商...

3598
来自专栏hrscy

Swift开源项目-单糖

因为公司使用的是 Objective-C 开发 app,没有使用 swift 来开发,所以决定自己研究 Swift,研究 Swift 的时间不长,对于 Swif...

1152
来自专栏贾老师の博客

Lua 游戏开发学习

1442
来自专栏北京马哥教育

DNS服务器之理论基础

一、什么是DNS DNS全称为Domain Name System,即域名系统,其作用就是将我们经常使用的“网址”解析为IP地址。 在互联网上...

3085
来自专栏沈唁志

几款常见的PHP模板引擎

1914
来自专栏java一日一条

我的编码习惯 - 配置规范(导读)

工作中少不了要制定各种各样的配置文件,这里和大家分享一下工作中我是如何制定配置文件的,这是个人习惯,在我在的项目组中目前要定义配置文件都安装这个步骤,效果还不错...

702

扫码关注云+社区