最近学习前端也有段时间了,从最基础的HTML/CSS/JS现在流行的Vue框架都有所接触,个人感觉前端和客户端开发还是有很多相似之处的,但是整体比较的话,前端更加的工程化,从打包工具(webpack, rollup等)一直到组件化框架(react,vue等)都有各种各样完整的工具链,这些工具链大部分由前端社区完成。当然了,这些东西Android/iOS开发也有,不过大部分是由厂商完成,开发社区只是做了些边边脚脚的框架,所以技术的更迭速度还是有落后于前端的。

前端的技术生态虽然百花齐放,但是根本原理跟Android开发还是很像的。举个例子,从渲染方面看,Android里面所有控件都是View,前端中HTML的每个节点在DOM中都是Element

Android的View体系称为view hierarchy,可以把它看成一个View组成的树形结构,在运行时生成,最顶层是ViewRootImpl,由ViewRootImpl负责测量所有View的大小并设置摆放位置(performMeasure等),然后收集它们的绘制命令(drawOperation),最后统一传递给GPU进行绘制。底层View分别可以通过invalidate,requestLayout请求重绘和重新计算位置,当然了,这必然引起ViewRootImpl重新进行一次遍历。

前端中承担view hierarchy责任的家伙称为DOM,这是一个存在于浏览器中的对象,浏览器通过请求得到HTML/CSS后,会分别将HTML和CSS解析成DOM和CSSOM。其中DOM就是一个树形层级结构,每层的叶子节点称为Element(即div之类的标签)。每个Element会结合CSSOM(根据CSS规则计算层叠)确定自己的样式和大小。 样式确定完毕后,此时DOM顶层会发起reflow确定位置和redraw收集绘制命令并发送给GPU(与Android很像)。 同样的,如果底层的Element的CSS或者属性发生改变了,那么可能会再次reflow或者redraw,通知DOM重新遍历,进行刷新。

可以看出来在绘制上还是和Android很类似吧,然而这只是其中一个很小的方面,具体等之后的文章再详细介绍。:)

还是继续说下前端技术栈,我用这些技术写了一个前端Demo,本文也是围绕这个Demo来分析是如何使用这些前端框架的,大家可以点击下面的链接看下。

vue-echo 注意播放时会有声音。

代码地址

所用前端技术栈:

  • Vue.js –响应式/组件化前端框架。
  • Vuex –vuex中的状态管理库。
  • Vue-Router –vue组件/页面间的路由管理。
  • Stylus –CSS预编译框架,与LESS/SASS类似。
  • mock.js –假数据模拟。
  • flexible-rem –淘宝移动端页面适配库。

HTML/CSS/JS这些比较基础,暂时就跳过了,下面逐一分析下这些框架的使用。

Vue.js

vue官网
Vue.js 近两年在前端社区很受欢迎,它是一款基于MVVM的组件化框架,配合Vue-Router可以方便的构建单页应用(SPA)。
关于vue,网上的文章也很多,我就不详细说了,这里只介绍最核心的亮点,MVVM组件化

关于MVVM

MVVMParrern

接触前端时间尚浅,不确定MVVM这种设计是什么时候开始流行的,但目前小程序/快应用的框架也是采用的这种设计,从趋势上看也是逐渐走向主流了。
我们先看下MVVM是怎么个设计,先看下面一张图。

图中有三种角色,分别是View,ViewModel,Model。
View可以理解为我们的UI,在前端里可以看成是DOM,更直白一点,就是HTML标签。
Model可以理解为需要渲染到DOM上的数据,这些数据可以来自网络请求,也可以来自本地数据(indexed.db,webstorage)之类的,比如显示个文字,图片之类的。
最关键的可以说是ViewModel了,在MVVM的设计中ViewModel承载Model数据,并与View实现双向绑定,可以认为ViewModel是连接View和Model的一个桥梁。

ViewModel与View实现的是双向绑定,简单点说,就是View的变化会通过ViewModel传递给Model。
举个例子,一个单选框点击选中,这个就是View的变化(具体是HtmlInputElement中checked属性的变化),它的变化通过ViewModel反映到Model中,告诉Model这条数据已经选中了。

反过来说,Model的数据也会自动传递给View进行渲染,同时其他逻辑(非View)造成的Model变化,View也能捕捉到,并自动重新渲染。

Vue框架就是实现了这个ViewModel的角色,它把通过模板语法把Html和Model结合起来,让Html自动捕获Model的变化。写个简单的Demo演示下。
我写个简单的Html,尽可能精简其他没关的内容。

这里只写了一个div,它的id是’app’,之所以要写id,是以为之后Vue需要找到它,并注入自己管理的虚拟DOM。
下面编写Vue逻辑。

初始Vue时传入的data即可理解为Model,Vue会将自己管理的虚拟DOM注入到#app这里,同时会自动监听data中msg字段的变化,msg的任何变化,都会反映到div标签中。
这些操作完全是Vue自动帮我们完成的,可以说省了一大部分代码,大部分场景不用我们自己再操作DOM了。
这个例子虽然简单,但是可以足够清晰说明MVVM架构了。

关于组件化

组件化这个功能在Vue中也实现的很好,这也是它至今如此流行的原因吧。
组件化的意思就是在项目中很多UI/逻辑需要复用,同时修改的话也需要统一修改,这个时候就可以把这些逻辑和UI封装成组件,Vue中称为Component。
Component中可以嵌套其他子Component,它们之间通过props这一机制进行通信。

Vue使用webpack来处理打包逻辑,Vue也依托于webpack实现了一套单文件系统来更好的支持Component。
比如我们创建一个HelloVue组件,那么可以建立一个HelloVue.vue文件。

相当于一个文件中html/css/js都有了,可以把逻辑封装到这里,然后外界依赖该组件,就可以调用了。

不多说了,具体可以点击这里看vue官网的介绍。

Vuex

Vuex官网
Vue采用一种单向数据流的设计,其中有三个关键角色,View, Action,State。

单向数据流图示

我们来看下这个图示,View接收用户事件,引起Action,Action会通知Store中的数据变化,Store变化后会重新渲染View,这就是一个完整单向的数据流。
举个简单的demo来看下这三个角色在Vue中的代码。

逻辑简单的话,单向数据流很简单明了,但是如果我们使用的组件比较多且需要大量共享状态时,使用props传值会非常麻烦,这个时候可以考虑使用Vuex。

Vuex是Vue上的一个状态管理插件,在使用Vue的过程中,Vuex不是必须的,比如如果状态只在组件内,那么就完全不需要使用Vuex。
就像刚才所说,但是如果我们的项目比较复杂,需要比较多的状态去管理,以上面的这个vue-echo 为例,有很多Component依赖这个播放状态,
比如根据是否播放来决定按钮是显示播放的icon还是暂停的icon。当然了,我们可以使用props这一组件间传递属性的方式来共享这一状态,这样做的话我们每开发一个跟播放有关的组件
就需要添加一个播放状态的props

Vuex的出现给我们解决了这个问题,使用Vuex可以将状态存放在一个全局对象中,可以认为这个全局存放状态的对象是个单例,在Vue的任何组件中,都可以使用这个单例的状态,
同时任何组件中也可以更改这个单例中的状态,当然了,这一切都是响应式的,这个单例的状态也可以认为是Model,通过Vue,这个Model的变化可以返回到任何监听状态的组件上。

Vue-Router

Vue-Router官网

说到前端的router,不得不提一下单页应用(SPA)。

SPA可以说是当前前端开发的一个趋势,简单来说就是只有一个Html,通过脚本来实现页面的切换,比如Vue在Vue-Router的支持下,就可以成为开发SPA的框架。

SPA有很多优点,比如说可以提高渲染效率,切换页面时,不用重新加载HTML和CSS,这样既减少了服务器压力,也提高了渲染速度,因为这些Element只是从DOM树中移到内存中了,
再次需要渲染这些Element时,直接从内存中拿出插入DOM即可。

Vue-Router的使用也非常简单,就不再这里举例了。

最后

这次我们分析了Vue, Vuex, Vue-Router这几个框架,有很多新概念的提出,可以看出前端这些年的演进还是很快的。
从当年流行的jQuery到现在大火的Vue/React,技术跟业务一样都在飞速发展,现在的web页面的复杂性也丝毫不比Native的App低。
当然了前端技术栈远远不止这些,我以后会继续写文章分析前端的技术栈,如果有说的不对的地方,欢迎大家指出。:)

2 对 “前端技术栈初探”的想法;

  1. 你好,我最近在GitHub上有幸发现并下载并学习了您的在16年发布的Android机票预订系统,现在遇到的问题是SQLite数据库无法连接并修改数据,以及找不到修改用户界面的相关代码。请问您能在百忙中抽空帮我看一下和指导一下吗,谢谢。如果可以能回复下你的联系方式吗。

发表评论

电子邮件地址不会被公开。 必填项已用*标注