随着大前端时代的到来,我们从 jquery 到 react,vue 等框架的转变,其实就是事件驱动到数据驱动的思维模式的转变
JQuery与vue最大的区别是,JQuery是事件驱动,而vue是数据驱动。 JQuery业务逻辑和UI更改该混在一起,
UI里面还参杂这交互逻辑,让本来混乱的逻辑更加混乱。
vue双向绑定
vue是双向绑定,vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)。
react是一种开发理念,组件化,分治的管理,数据与view的一体化。它只有一个中心,发出状态,渲染view,对于虚拟dom它并没有提高渲染页面的性能,它提供更多的是利用jsx便捷生成dom元素,利用组件概念进行分治管理页面每个部分(例如header section footer slider)
事件驱动
事件是可以被控件(控件是用户可与之交互以输入或操作数据的对象)识别的操作,如按下确定按钮,选择某个单选按钮或者复选框。每一种控件有自己可以识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事件,等等。
事件(event)是针对应用程序所发生的事情,并且应用程序需要对这种事情做出响应。
事件处理
程序对事件的响应其实就是调用预先编制好的代码来对事件进行处理,这种代码称为事件处理程序(event handler)。
事件驱动编程(event-driven programming)
就是针对这种“程序的执行由事件决定”的应用的一种编程范型。
Event loop
主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
事件驱动思维
在GUI和Javascript的设计场景下,我们写代码的时候也会代入这样的思维: 用户输入 => 事件响应 => 代码运行 => 刷新页面状态
刚开始写应用的思路如下:
1.开发静态页面。
2.添加事件监听,包括用户输入、http请求、定时器触发等事件。
3.针对不同事件,编写不同的处理逻辑,包括获取事件状态/输入、计算并更新状态等。
4.根据计算后的数据状态,重新渲染页面。通俗地说,事件驱动思维是从事件响应出发,来完成应用的设计和编程。
数据驱动
数据驱动,将我们从复杂的逻辑设计带进数据处理的世界。
何为数据
数据是什么,官方回答:数据是科学实验、检验、统计等所获得的和用于科学研究、技术设计、查证、决策等的数值。
但其实不管是资料中、生活和工作中,所有的事物我们都可以抽象为数据。像游戏里面的角色、物品、经验值、天气、时间等等,都是数据。游戏其实也算是对真实世界抽象的一种,而抽象之后,最终都可呈现为数据。总结起来,数据是一个抽象的过程。
回到日常写代码中,前端写页面,抽象成数据常用的无非是:
1.列表 => array
2.状态 => number/boolen
3.一个卡片 => object
4.等等
数据驱动 vs 事件驱动
事件驱动
1.构建页面:设计DOM => 生成DOM => 绑定事件
2.监听事件:操作UI => 触发事件 => 响应处理 => 更新UI
数据驱动
1.构建页面:设计数据结构 => 事件绑定逻辑 => 生成DOM
2.监听事件:操作UI => 触发事件 => 响应处理 => 更新数据 => 更新UI
区别
其实最大的转变是,以前会把组件视为DOM,把事件/逻辑处理视为Javascript,把样式视为CSS。而当转换思维方式之后,组件、事件、逻辑处理、样式都是一份数据,我们只需要把数据的状态和转换设计好,剩下的实现则由具现方式(模版引擎(vue)、事件机制(jQuery)等)来实现。
转换到数据驱动思维后,我们在编程实现的过程中,更多的是思考数据的维护和处理,而无需过于考虑UI的变化和事件的监听。
数据驱动思维
转换到数据驱动思维后,我们在编程实现的过程中,更多的是思考数据的维护和处理,而无需过于考虑UI的变化和事件的监听。
拿一个企业网站来说,里面的很多数据和链接,从前我们常用方式是直接写成DOM,然后就产生了很长的一段DOM代码。
如果说我们将其切换到数据,以对象和数组的方式存储,这时候我们只需要写一段具现方式,将这组数据转成DOM。这种方式有以下好处:1.数据变更方便
2.DOM结构变轻
3.DOM结构/样式调整方便
4.抽象设计
5.代码量减少,易于维护
数据驱动与mvvm
数据驱动的设计思维或许与mvvm没有必然的联系,但是mvvm框架提供一些具现方式将数据驱动变得更加轻松。
mvvm集成具现化方法
拿vue框架来说,有以下一些很方便的具现方法:
1.模板渲染:数据 => AST => 生成DOM
2.数据绑定:交互输入/http请求响应/定时器触发 => 事件监听 => 数据变更 => diff => DOM更新
3.路由引擎:url => 数据(host/path/params等) => 解析对应页面
当我们使用了这些mvvm框架时,它们解决了如何让数据转变成需要的东西,将抽象具象化的问题。在这样的情况下,我们只需要完成两步:
1.将产品/业务/设计抽象化,将UI、交互抽象为数据。
2.将一组组的数据用逻辑处理连接起来。
mvvm推动数据驱动思维
这里借用vue,来举两个例子。
一、获取input输入并更新
实现一个input的监听输入,并更新输出到模板,我们能有以下代码的变化:
<!--1.事件驱动-->
<input type="text" id="input"/>
<p id="p"></p>
<script>
$('#input').on('click',e=>{
const val = e.target.value;
$('#p').text(val);
})
</script>
<!--2.数据驱动 + vue-->
<input type="text" v-model="inputValue"/>
<p>{{inputValue}}</P>
<!--当我们在vue中,模板引擎帮我们处理了模板渲染、数据绑定的过程,我们只需要知道这里面只有一个有效数据,即input的值。-->
二、部分更新列表
我们再来看个例子,我们有一组数据,需要渲染成一个列表:
const list = [
{id:1,name:'name1',href:'http://href1'},
{id:2,name:'name2',href:'http://href2'},
{id:3,name:'name3',href:'http://href3'},
{id:4,name:'name4',href:'http://href4'},
]
1、当我们需要渲染成列表时:
<!--1.事件驱动-->
<ul id='ul'></ul>
<script>
const dom = $('#ul');
list.forEach(item=>{
dom.append(`<li data-id="${item.id}"><span>${item.name}</span>:<a href="${item.href}">${item.href}</a></li>);
})
</script>
<!--2.数据驱动 + vue-->
<ul>
<li v-for="item in list":key="item.id"><span>{{item.name}}</span><a: href="itme.href">{{itme.href}}</a></li>
</ul>
2、当我们需要更新一个列表中某个id的其中一个数据时(这里需要更改id为3的name值):
//1).事件驱动
const dom = $('#ul');
const id = 3;
dom.find(`li[data-id="${id}"]span`).text('newName3');
//2).数据驱动 + vue
const id = 3;
const item3 = list.find(item=>item.id==3);
if(item3 ) item3.name=='newName';
> 在使用数据驱动的时候,模板渲染的事情会交给框架去完成,我们需要做的就是数据处理而已。