一、Angular
Angular的属性绑定语法为[attr]=porperty
,事件绑定语法为(event)=fn
。双向绑定的使用存在两种场景:
1、在表单中双向绑定使用[(ngModel)]=porperty
,但同时得设置name
属性。其等价于绑定属性[value]=property + 绑定事件(input)=porperty.value = input.value
。
2、父子组件通信中,存在@Input
和@Output
语法,在子组件中使用输入属性和输出属性,输出属性的名称是输入名称再加上Change
(避免在父组件模板上添加自定义事件和在控制器中添加事件处理程序)。然后在父组件模板引用子组件的标签上添加[(attr)]=porperty
。
二、AngularJs
angularJs有脏检查机制,主要是依据$watch
对象来监测数据是否更新。可以通过$apply
和$digest
两个函数来手动触发检测。这个和基于setter
的检测机制不同,不能够做到在数据更新时执行操作,而只能通过事件入口执行检查,确认数据更新后再更新视图。
一般情况下$apply
和$digest
执行效果相同,但是$apply
可以带上参数可在变更后执行某个方法,并且$digest
方法只触发当前作用域和它的子作用域上的监控,而$apply
是触发整个作用域上的监控。所以在保证只变更当前或子级作用域的情况下,调用$digest
性能会高出$apply
。
脏检查的性能问题一直被讨论,相较基于setter的检测机制来说,如果在处理循环更新DOM
元素的情况,脏检查可以先检查所有的更新,构建好整个DOM
结构,然后一次整体更新,相较于setter
的分次更新来说性能反而会更高。
三、Vue.js
Vue.js是通过数据劫持结合发布者-订阅者模式的方式来实现的。用户操作会更改某个属性的值,而通过重写该属性的set
方法,对数据进行劫持监听,可以在每次值更新的时候,执行重写的set
方法内的指定操作。这里的指定操作即是判断数据是否更新,是否需要更新视图。如果确认更新则修改当前视图。
四、React
React本身并没有提到双向绑定的概念,但是可以基于setState
和onChange
事件实现数据层于视图层的同步更新。例如每次修改表单值时执行onChange
事件,调用setState
更新数据层,从而更新视图。