大前端的概念一而再再而三的被提及,那么大前端时代究竟是什么呢?大前端这个词最早是因为在阿里内部有很多前端开发人员既写前端又写 Java 的 Velocity 模板而得来,不过现在大前端的范围已经越来越大了,包含前端 + 移动端,前端、CDN、Nginx、Node、Hybrid、Weex、React Native、Native App。笔者是一名普通的全职 iOS 开发者,在接触到了前端开发以后,发现了前端有些值得移动端学习的地方,于是便有了这个大前端时代系列的文章,希望两者能相互借鉴优秀的思想。谈及到大前端,常常被提及的话题有:组件化,路由与解耦,工程化(打包工具,脚手架,包管理工具),MVC 和 MVVM 架构,埋点和性能监控。笔者就先从组件化方面谈起。网上关于前端框架对比的文章也非常多(对比 React,Vue,Angular),不过跨端对比的文章好像不多?笔者就打算以前端和移动端(以 iOS 平台为主)对比为主,看看这两端的不同做法,并讨论讨论有无相互借鉴学习的地方。
一. 组件化的需求
为了提高代码复用性,减少重复性的开发,我们就把相关的代码按照 template、style、script 拆分,封装成一个个的组件。组件可以扩展
HTML 元素,封装可重用的 HTML 代码,我们可以将组件看作自定义的 HTML 元素。在 Vue 里面,每个封装好的组件可以看成一个个的 ViewModel。
二. 如何封装组件
谈到如何封装的问题,就要先说说怎么去组织组件的问题。
如果在简单的 SPA 项目中,可以直接用 Vue.component 去定义一个全局组件,项目一旦复杂以后,就会出现弊端了:
- 全局定义(Global definitions) 强制要求每个 component 中的命名不得重复
- 字符串模板(String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
- 不支持 CSS(No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
- 没有构建步骤(No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
而且现在公司级的项目,大多数都会引入工程化的管理,用包管理工具去管理,npm 或者 yarn。所以 Vue 在复杂的项目中用 Vue.component 去定义一个组件的方式就不适合了。这里就需要用到单文件组件,还可以使用 Webpack 或 Browserify 等构建工具。比如下面这个Hello.vue组件,整个文件就是一个组件。
在单文件组件中,整个文件都是一个 CommonJS 模块,里面包含了组件对应的 HTML、组件内的处理逻辑 Javascript、组件的样式 CSS。
在组件的 script 标签中,需要封装该组件 ViewModel 的行为。
- data
组件的初始化数据,以及私有属性。
- props
组件的属性,这里的属性专门用来接收父子组件通信的数据。(这里可以类比 iOS 里面的 @property )
- methods
组件内的处理逻辑函数。
- watch
需要额外监听的属性(这里可以类比 iOS 里面的 KVO )
- computed
组件的计算属性
- components
所用到的子组件
- lifecycle hooks
生命周期的钩子函数。一个组件也是有生命周期的,有如下这些:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deactivated、beforeDestroy、destroyed等生命周期。在这些钩子函数里面可以加上我们预设的处理逻辑。(这里可以类比 iOS 里面的 ViewController 的生命周期 )
如此看来,在 Vue 里面封装一个单文件组件,和在 iOS 里面封装一个 ViewModel 的思路是完全一致的。接下来的讨论无特殊说明,针对的都是单文件组件。
三. 如何划分组件
一般划分组件分可以按照以下标准去划分:
- 页面区域:
header、footer、sidebar……
- 功能模块:
select、pagination……