Vue.js:轻量高效的前端组件化方案

作者:wy日期:2016-06-30 13:41:46 点击:111 Vue.js

开发初衷

由于感到Angular的API设计过于繁琐,使得学习曲线颇为陡峭,同时在实际开发中,我发现用户界面完全可以用嵌套的组件树来描述,而一个组件恰恰可以对应MVVM中的ViewModel。于是决定将我的数据绑定实验改进成一个真正的开源项目,其核心思想便是 “数据驱动的组件系统”。

MVVM 数据绑定

MVVM的本质是通过数据绑定链接View和Model,让数据的变化自动映射为视图的更新。Vue.js在数据绑定的API设计上借鉴了Angular的指令机制:用户可以通过具有特殊前缀的HTML 属性来实现数据绑定,也可以使用常见的花括号模板插值,或是在表单元素上使用双向绑定

插值本质上也是指令,只是为了方便模板的书写。在模板的编译过程中,Vue.js会为每一处需要动态更新的DOM节点创建一个指令对象。每当一个指令对象观测的数据变化时,它便会对所绑定的目标节点执行相应的DOM操作。基于指令的数据绑定使得具体的DOM操作都被合理地封装在指令定义中,业务代码只需要涉及模板和对数据状态的操作即可,这使得应用的开发效率和可维护性都大大提升。

与Angular不同的是,Vue.js的API里并没有繁杂的module、controller、scope、factory、service等概念,一切都是以“ViewModel 实例”为基本单位

数据观测的实现

Vue.js利用了ES5的Object.defineProperty方法,直接将原生数据对象的属性改造为getter和setter,在这两个函数内部实现依赖的收集和触发,而且完美支持嵌套的对象结构。对于数组,则通过包裹数组的可变方法(比如push)来监听数组的变化。这使得操作Vue.js的数据和操作原生对象几乎没有差别[注:在添加/删除属性,或是修改数组特定位置元素时,需要调用特定的函数,如obj.$add(key, value)才能触发更新。这是受ES5的语言特性所限。],数据操作的逻辑更为清晰流畅,和第三方数据同步方案的整合也更为方便。

组件系统

在大型的应用中,为了分工、复用和可维护性,我们不可避免地需要将应用抽象为多个相对独立的模块。在较为传统的开发模式中,我们只有在考虑复用时才会将某一部分做成组件;但实际上,应用类 UI 完全可以看作是全部由组件树构成的

因此,在Vue.js的设计中将组件作为一个核心概念。可以说,每一个Vue.js应用都是围绕着组件来开发的。

Vue.js的组件可以理解为预先定义好了行为的ViewModel类。一个组件可以预定义很多选项,但最核心的是以下几个:

?  模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。

?  初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。

?  接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。参数默认是单向绑定(由上至下),但也可以显式地声明为双向绑定。

?  方法(methods):对数据的改动操作一般都在组件的方法内进行。可以通过v-on指令将用户输入事件和组件方法进行绑定

?  生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,比如created,attached,destroyed等等。在这些钩子函数中,我们可以封装一些自定义的逻辑。和传统的MVC相比,可以理解为 Controller的逻辑被分散到了这些钩子函数中。

?  私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。由于全局注册资源容易导致命名冲突,一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。

Vue.js提供了完善的定义、复用和嵌套组件的API,让开发者可以像搭积木一样用组件拼出整个应用的界面。

Vue.js还有几个值得一提的特性:

?  异步批量DOM更新:当大量数据变动时,所有受到影响的watcher会被推送到一个队列中,并且每个watcher只会推进队列一次。这个队列会在进程的下一个 “tick” 异步执行。这个机制可以避免同一个数据多次变动产生的多余DOM操作,也可以保证所有的DOM写操作在一起执行,避免DOM读写切换可能导致的layout。

?  动画系统:Vue.js提供了简单却强大的动画系统,当一个元素的可见性变化时,用户不仅可以很简单地定义对应的CSS Transition或Animation效果,还可以利用丰富的JavaScript钩子函数进行更底层的动画处理。

?  可扩展性:除了自定义指令、过滤器和组件,Vue.js还提供了灵活的mixin机制,让用户可以在多个组件中复用共同的特性

与Web Components的异同

Web Components是一套底层规范,本身并不带有数据绑定、动画系统等上层功能,因此更合适的比较对象可能是Polymer。Polymer在API和功能上和Vue.js比较相似,但它对Web Components的硬性依赖使得它在浏览器支持方面有一定的问题——在不支持Web Components规范的浏览器中,需要加载庞大的polyfill,不仅在性能上会有影响,并且有些功能,比如ShadowDOM,polyfill并没有办法完美支持。同时,Web Components规范本身尚未定稿,一些具体设计上仍存在不小的分歧。相比之下,Vue.js在支持的浏览器中(IE9+)没有任何依赖。

除此之外,在支持Web Components的环境中,我们也可以很简单地利用Web Components底层API将一个Vue.js组件封装在一个真正的自定义元素中,从而实现Vue.js组件和其他框架的无缝整合。

总结:

vue.js由于其轻量(22kb min+gzip)、高性能的特点,对于移动场景也有很好的契合度。更重要的是,设计完备的组件系统和配套的构建工具、插件,使得Vue.js在保留了其简洁API的同时,也已经完全有能力担当起复杂的大型应用的开发。

上一篇: 返回列表

下一篇: Vue.js相对于Angular.js和React.js的优势