深入了解Vue.js轻量级高效的前端组件化方案
Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统。在前端复杂的生态中,Vue.js受到了一定程度的关注,GitHub上已经有5000星了。本文将从各个方面对Vue.js进行深入的介绍。
Vue.js是我在2014年2月开放的一个前端开发库。它通过简单的API提供高效的数据绑定和灵活的组件系统。在前端复杂的生态中,Vue.js受到了一定程度的关注,GitHub上已经有5000星了。本文将从各个方面对Vue.js进行深入的介绍。
发展初衷
2013年底,我还在谷歌创意实验室工作。当时,Angular在项目中使用了一段时间。在感叹数据绑定带来的生产力提升的同时,也觉得Angular API的设计过于繁琐,使得学习曲线陡峭。出于对Angular数据绑定原理的好奇,我开始“造轮子”,实现了一个非常粗糙的基于依赖集合的数据绑定库。这是Vue.js的前身同时在实际开发中,我发现用户界面可以用嵌套的组件树来描述,一个组件完全可以对应MVVM的ViewModel。所以我决定把我的数据绑定实验改进成一个真正的开源项目,其核心思想是“数据驱动的组件系统”。
MVVM数据绑定
MVVM的本质是通过数据绑定将视图和模型链接起来,这样数据的变化就可以自动映射到视图的更新上。Vue.js在数据绑定的API设计中借鉴了Angular指令机制:用户可以通过带有特殊前缀的HTML属性实现数据绑定,也可以使用常用的花括号模板进行插值,或者对表单元素使用双向绑定;
!-说明-span v-text=' msg'/span!-插值-span {{msg}}/span!-双向绑定-输入v-model=' msg '插值本质上也是一个指令,只是为了方便编写模板。在编译模板的过程中,Vue.js会为每个需要动态更新的DOM节点创建一个指令对象。每当指令对象观察到的数据发生变化时,都会在绑定的目标节点上执行相应的DOM操作。基于指令的数据绑定使得具体的DOM操作能够合理地封装在指令定义中,业务代码只需要涉及模板和对数据状态的操作,大大提高了应用程序的开发效率和可维护性。
与Angular不同,Vue.js的API中没有模块、控制器、范围、工厂、服务等复杂的概念,一切都基于“ViewModel实例”:
!-template-div id=' app ' { msg } }/div//原始对象是data var data={msg: 'hello!'}//创建一个ViewModel实例var vm=new Vue({ //选择目标元素el: '#app ',//提供初始数据data: data})渲染结果:
div id='app '你好!/div在渲染的同时,Vue.js已经完成了数据的动态绑定:此时如果data.msg的值发生变化,DOM会自动更新。很容易理解吗?此外,Vue.js大大简化了自定义指令和过滤器的API。如果你有Angular开发经验,你会很快上手。
数据观测的实现
Vue.js的数据观测实现原理与Angular有本质区别。了解Angular的读者可能知道,Angular的数据观测采用了脏检查机制。每个指令将有一个相应的对象来观察数据,称为观察者;在一个范围内会有很多观察者。每当接口需要更新时,Angular将遍历当前范围内的所有观察器,逐个评估它们,然后将它们与之前保存的旧值进行比较。如果评估结果发生变化,则会触发相应的更新。这个过程叫做消化循环。脏检查有两个问题:1。任何数据更改都意味着当前范围内的每个观察器都需要重新评估。因此,当观察者数量巨大时,应用的性能必然会受到影响,难以优化。2.当数据发生变化时,框架无法主动检测到变化,需要手动触发摘要周期来触发相应的DOM更新。Angular通过在DOM事件处理程序中自动触发摘要循环来避免这个问题,但是仍然有很多情况需要用户手动触发。
Vue.js采用了基于依赖集合的观察机制。原则上与老MVVM框架淘汰赛相同。依赖项收集的基本原则如下:1。将原始数据转化为“可观察的对象”。一个可观察的对象可以被赋值或赋值。2.在观察者的评估过程中,每一个有值的可观察对象都会将当前观察者注册为自身的订阅者,成为当前观察者的依赖者。3.当一个依赖的可观察对象被分配时,它将通知所有订阅它的观察者重新评估并触发相应的更新。4.依赖项收集的优点是可以准确主动地跟踪数据的变化,没有上面提到的脏检查的两个问题。但依赖集合的传统实现,如敲除,通常需要包装原生数据,使之成为可观察的对象,取值赋值时需要使用函数调用的形式,操作数据时繁琐且不直观;同时,对象对复杂嵌套结构的支持也不理想。
Vue.js通过使用ES5的Object.defineProperty方法,直接将原生数据对象的属性转换为getter和setter,并在这两个函数内收集和触发依赖关系,完美支持嵌套对象结构。对于数组,我们可以通过包装数组的变量方法(比如push)来监听数组的变化。这使得操作Vue.js数据和操作原生对象几乎没有区别[注:在数组特定位置添加/删除属性或修改元素时,需要调用特定的函数,如obj。$add(键,值),以触发更新。这受限于ES5的语言特点。】,数据操作逻辑更清晰流畅,与第三方数据同步方案集成更方便。
组件系统
在大规模应用中,为了分工、重用和可维护性,我们不可避免地需要将应用抽象成多个相对独立的模块。在比较传统的开发模式中,我们在考虑复用的时候只把某个部分做成一个组件;但实际上,应用类UI可以看作完全由组件树组成:
所以,组件是Vue.js设计中的一个核心概念,可以说,每一个Vue.js应用都是围绕组件开发的。
注册Vue.js组件非常简单:
Vue.component ('my-component ',{//template template : ' div { { msg } } { { private msg } }/div ',//接受参数prop : { msg 3360 string br },//private data。您需要在函数中返回,以避免多个实例共享一个对象data : function(){ return { privatesg 3360 ' component!}} }})
注册后,您可以在父组件模板中以自定义元素的形式调用子组件:
我的组件消息='你好'/我的组件
渲染结果:
divhello组件!/div
Vue.js的组件可以理解为具有预定义行为的ViewModel类。可以为组件预定义许多选项,但核心选项如下:
模板:模板声明最终呈现给用户的数据和DOM之间的映射关系。初始数据:组件的初始数据状态。对于可重用组件,这通常是私有状态。可接受的外部参数(道具):数据通过参数在组件之间传输和共享。默认情况下,参数是单向绑定的(从上到下),但也可以显式声明为双向绑定。方法:数据修改操作一般在组件的方法中进行。您可以通过v-on指令将用户输入事件绑定到组件方法。生命周期挂钩:一个组件可以触发多个生命周期挂钩,如创建、附加、销毁等。在这些钩子函数中,我们可以封装一些自定义逻辑。与传统的MVC相比,可以理解控制器的逻辑被分散到这些钩子函数中。私有资产:在vue.js中,用户定义的指令、过滤器和组件统称为资源。因为全局注册资源容易导致命名冲突,所以组件可以声明自己的私有资源。私有资源只能调用这个组件及其子组件。
此外,同一组件树中的组件可以通过内置的事件应用编程接口进行通信。Vue.js为定义、重用和嵌套组件提供了一个完整的API,这样开发人员就可以像构建块一样用组件拼出整个应用程序界面。这个想法的可行性在脸书的开源React中也得到了证实。
基于构建工具的单文件组件格式
Vue.js的核心库只提供了基本的API,并没有对如何组织应用程序的文件结构做太多的约束。但是,在构建大规模应用程序时,建议使用Webpack vue-loader的组合,以使组件的开发更加高效。
Webpack是Tobias Koppers开发的开源前端模块构建工具。它的基本功能是将几个以模块格式编写的JavaScript文件打包成一个文件,同时还支持CommonJS和AMD格式。但与众不同的是,它提供了一个强大的加载器API来定义不同文件格式的预处理逻辑,这样我们就可以使用CSS、模板甚至自定义文件格式作为JavaScript模块。基于loader,Webpack还可以实现大量的高级功能,如自动分块打包和按需加载、自动定位图像资源引用、根据图像大小决定是否使用base64内联、开发时热模块替换等。可以说是目前前端建设领域最具竞争力的解决方案之一。
我基于Webpack的loader API开发了Vue-loader插件,这样我们就可以用这样单一的文件格式(*)编写Vue组件。vue):
style . my-component H2 { color : red;}/style template div class=' my-component ' h2Hello from { { msg } }/H2 other-component/other-component/div/template script//根据CommonJS模块格式var other component=require('。/other-component ')//导出组件定义模块。exports={ data : function(){ return { msg : ' vue-loader ' } },components 3360 { ' other-component ' : other component } }/script。同时,您也可以在*中使用其他预处理程序。vue文件,只需安装相应的Webpack加载程序:
style lang='手写笔'。my-component H2 color red/style template lang=' jade ' div . my-component H2 Hello from { { msg } }/template script lang=' Babel '/Compile es 2015 export default { data(){ return { msg : ' Hello from Babel!像} }}/script这样的组件格式将组件的模板、样式和逻辑集成到同一个文件中,便于开发、重用和维护。另外,Vue.js本身支持组件的异步加载,配合Webpack的块打包功能,实现组件的按需异步加载极其容易。
其他特征
Vue.js还有几个值得一提的特性:
1.异步批处理DOM更新:当大量数据发生变化时,所有受影响的观察器都会被推送到一个队列中,每个观察器只会推一次队列。该队列将在进程的下一个“滴答”处异步执行。这种机制可以避免同一数据多次变化带来的冗余DOM操作,也可以保证所有的DOM写操作一起执行,从而避免了DOM读写切换带来的可能布局。2.动画系统:Vue.js提供了一个简单但功能强大的动画系统。当一个元素的可见性发生变化时,用户不仅可以简单地定义相应的CSS Transition或动画效果,还可以使用丰富的JavaScript hook函数在较低的级别执行动画处理。3.可扩展性:除了自定义指令、过滤器和组件之外,Vue.js还提供了灵活的mixin机制,允许用户在多个组件中重用公共特性。
与网络组件的异同
了解Web Components的读者可能会在这里有疑问:Vue.js的组件和Web Components的组件有什么区别?这里简单分析一下。
Web Components是一组底层规范,没有数据绑定、动画系统等上层功能,所以比较合适的比较对象可能是Polymer。Polymer在API和功能上与Vue.js类似,但其对Web Components的刚性依赖,使其在浏览器支持上存在一些问题,——在不支持Web Components规范的浏览器中,需要加载一个巨大的polyfill,不仅会影响性能,还会有一些无法完美支持的功能,比如ShadowDOM。同时,Web Components规范本身还没有最终确定,在一些具体的设计上还存在很多差异。相比之下,Vue.js在支持的浏览器(IE9)中没有任何依赖关系。
另外,在支持Web Components的环境中,我们可以简单地利用Web Components的底层API,将一个Vue.js组件封装在一个真实的自定义元素中,从而实现Vue.js组件与其他框架的无缝集成。
摘要
在发布之初,Vue.js最初专注于轻量级嵌入式使用场景。时至今日,Vue.js依然适用于这样的场景。由于其重量轻(22kb min gzip)和高性能,它也很适合移动场景。更重要的是,由于设计良好的组件系统、支持的构建工具和插件,Vue.js已经能够在保留其简洁的API的同时承担复杂的大规模应用程序的开发。
自诞生以来的一年半时间里,Vue.js经历了彻底的重构和数次API设计改进,目前已经趋于稳定。测试覆盖率长期保持在100%,GitHub Bug数量长期保持在个位数。世界各地的公司/项目已经将Vue.js应用到生产环境中。2015年晚些时候,Vue.js将发布1.0版本,敬请关注。
[参考链接]
Vue.js官方网站:http://vuejs.org
GitHub仓库:https://github.com/yyx990803/vue
Webpack官网: http://webpack.github.io
vue-loader单页组件示例:https://github.com/vuejs/vue-loader-example
摘要
以上就是边肖介绍的Vue.js轻量级高效的前端组件化方案。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!
版权声明:深入了解Vue.js轻量级高效的前端组件化方案是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。