使用 Vue.js 开发富交互式应用

| 导语 Vue.js 是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用。

本篇文章目录如下:

  • 技术选型及架构
  • 开发
  • 优化

技术选型及架构

常见的前端产品形态包括:

内容型Web站点 侧重渲染方面的优化,前端逻辑比重小
操作型B/S系统 以数据和逻辑为中心,界面较规整
内嵌Web的本地应用 要处理缓存和一些本地接口,包括PC客户端和移动端

技术选型不能想当然,既要根据产品的实际需求出发,又要考虑到项目研发团队成员的技术储备和项目经验。

在谈前端架构之前,需要先探讨一下不同人群对前端产生的困惑。前端这个职业最近几年才逐渐被认可,之前一直是低端的代名词,所以多数高手很不屑搞这个。之前的很多项目,人们对前端这块的要求也只是能用就行,所以很少会在上面去细致、深入地建立一套完善体系。而多数产品的技术经理也会是后端出身的,往往对前端的认识还停留在 Java Struts 那个原始的 MVC 模型上,或者首先想到的就是 GWT 和 JSF,这是从后端角度出发的一种视角。用这类思维方式做出来的产品,一般用户体验都不会很好。

canvas 图片生成项目是一款强交互式的 Web 端产品,根据产品的需求和对现有项目团队的技术实力以及以往的项目经验,最终敲定使用 Vuejs 框架来完成该项目。

canvas 图片项目使用的技术栈为Vue全家桶,通过 Vue Router 来处理前端路由的管理,借用 Vue Resource 来处理网络请求(官方不再推荐在项目中使用该库,推荐使用 axios 来处理网络请求)。目前的前端开发,通过组件开发模式已经是标配,他不仅能带来同队协作开发的便利,同时也能让我们的项目代码变得容易维护。组件的开发就涉及到组件的依赖管理和通信,所以我们引入了 vuex 库来完成组件间的通信。到此我们已经完成了开发项目的基础建设,但对开发调式的工作依旧没有很好的处理。在团队过往的项目中,使用过很多关于工作流的工具,包括但不限于像鼎鼎有名的 grunt/gulp 这样曾经红极一时的构建工具,也有团队基于开发 npm 包自研的构建工具。这些工具有一个通用的特点就是,更好的处理我们在开发和发布前遇到的手动处理的任务,比如 源码编译(coffee/sass)。项目成员调研了Webpack 和以往工具的优势,最终我们拥抱了 webpack, 它更倾向于组件和组件之间依赖的处理。

使用 Vue.js 开发富交互式应用

开发

完成基础项目的搭建之后,我们就可以动手码代码了。我们将组件进行了拆分,通用组件和业务组件。像头部/底部 这些组件基本是项目通用的,前期将他们拆分出来,对后期组件的复用帮助很大。业务组件通常是针对某一个具体的功能,实现上耦合度也较高。

首先来看看组件到底是什么样的:

组件引入

组件间通信
vue 中组件树跟 DOM 树很相似,所以组件关系有父子关系嵌套关系和同级关系或者不相关。父子嵌套关系可以通过 props 来给子组件传递数据,通过 event bus 来实现组件间的通信。但其他类型的组件关系, event bus 就无能为力或者变得难以维护。因此我们借助 vuex 来解决这些问题。看下demo效果先:

使用 Vue.js 开发富交互式应用

首先我们看下官方的解释:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

每一个 Vuex 应用的核心就是 store(仓库)。"store" 基本上就是一个容器,它包含着你的应用中大部分的状态(state)。Vuex 和单纯的全局对象有以下两点不同:Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

我们再项目源码目录创建了一个新的目录 vuex ,用来存放跟vuex 相关的任务代码

modules 目录存放了 store 仓库的模块。canvas 项目把整个仓库分为了两大类,一个菜单侧和主画布区。这样当应用变得很大时,store 对象也不会变得臃肿不堪。

自此,我们已经完成了 vuex 目录的设计,那么如何在我们的组件里如何引入呢?
首先,需要在入口文件 app.vue 导入 store.js 文件并在组件导出对象里定义 store 属性。其他的就交给 vue  框架处理吧。其次,需要再需要使用 vuex 的组件中,定义 vuex 属性,设置 actions 或 getters, 如果需要的话。

vuex 解决了大型应用组件通信的问题,如果你的应用很简单,并不必使用vuex,相反她可能增加你项目的复杂度。倒是 event bus 就很好的解决你的任务。

优化

字体加载
字体加载一直是项目过程的问题,为了让应用生成的图片更具有设计稿,网站引入了大量的版权字体,甚至是跨平台的字体也需要手动加载,常见字体(微软雅黑)也需要通过网络加载,才能保证各平台用户生成图片的一致性。上线初期,字体加载问题一直没有很好的解决,最初的方案是通过字体加载完成后再显示,这样就能保证用户看到的界面不会出现频繁闪烁。与此同时,也带来了另外的问题,如果页面内容使用了过多的字体,用户可能很长时间段都看不到内容,一直处于加载效果态,此外在测试期间还发现了另外一个严重的问题,有一个字体一天使用了 1.7G 的CDN流量,太可怕了,这些都是钱啊。优化字体体积才是我们现阶段需要解决的首要问题,最终方案是开启 gzip 和 转换字体格式。当然还有更优的解决方案,像字蛛方案。

图片生成
图片生成问题也是项目初期遇到的问题。最大的问题是生成图片和用户制作时的图片有视觉差异,最明显的就是字体渲染,前期项目使用了 wkhtmltopdf 库,该库在 Linux 环境对字体支持的不是很好,特别是中文字体,所以后期为了解决这个问题,把服务端的渲染引擎换成了phantomjs。也希望这种方案能解决有图片生成需求的其他同学。
组件优化
最后就是组件的优化了,更多的实践是我们需要让组件的职责更明确,所以对组件做了拆分和重构,这样如果有新的同学加入或添加新的需求,往往改动较少。此外之前使用大量的 broadcast 和 dispatch 实践分发机制,导致的问题就是组件难以维护,一旦有变动就需要修改引入组件的一些 events 对象,而且 2.0 也不再支持该功能。使用 vuex 方案就能很好的解决组件通信的问题。

总结

文章介绍了一个新项目的技术选型和前端架构的一些思考,然后针对具体的三方库做了介绍以及具体的使用方法,最后针对项目的问题做了分析并提供了解决方案。欢迎大家留言讨论,谢谢。

 

最后,推广一下我们团队的产品——canvas_瓦斯平台:

canvas图片设计平台(canvas.qq.com),新媒体运营利器!平台预置大量的模板和素材,操作简单没有门槛,只需要选择一个模板、通过简单的拖拽操作就可以制作图片。目前提供的模板类型包括公众号文章封面图、信息图和活动推广的海报、邀请函、会议通知等等。

体验地址:canvas.qq.com,(请使用chrome浏览器或者QQ浏览器的极速模式体验)

参考资源

Vuejs 官网: http://vuejs.org/

Vue Router 官网: https://router.vuejs.org/en/

Vuex 官网: https://vuex.vuejs.org/

博客资源: 徐飞的 github 博客