angular vue react原理解析

angular:双向数据绑定

脏数据监测:

在Angular中,有$apply和$digest两个函数:

$apply可以带参数,它可以接受一个函数,然后在应用数据之后,调用这个函数。

digest将会遍历我们的$watch:

  • 嘿,$watch,你的值是什么?
    • 是9。
  • 好的,它改变过吗?
    • 没有,先生。
  • (这个变量没变过,那下一个)
  • 你呢,你的值是多少?
    • 报告,是Foo
  • 刚才改变过没?
    • 改变过,刚才是Bar
  • (很好,我们有DOM需要更新了)
  • 继续询问知道$watch队列都检查过。

因为Angular的设计,同一时间只允许一个$digest运行,而ng-click这种内置指令已经触发了$digest,当前的还没有走完,所以就出错了。

 

 

vue:双向数据绑定

 

数据属性:数据属性包含一个数据值的位置,在这个位置可以读取和写入值.

 

访问器属性:访问器属性不包含数据值;他们包含一对getter和setter函数在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值,在写入访问器属性时,会调用setter函数并传入新值.

 

设置对象的访问器属性只能用es5的Object.defineProrerty()方法

每个属性都有get和set方法,在做双向的数据的控制都在get和set方法中,因为无论你是在ready(2.0是mounted了)或是在view中改变值都会触发set方法,将新值复制进去,在重新在view中匹配值,当然你们有更复杂的控制操作,get方法着是让ready中获取的这个属性值一直保存最新值.

 

 

每当 new 一个 Vue,主要做了两件事:第一个是监听数据:observe(data),第二个是编译 HTML:nodeToFragement(id)。

 

       在监听数据的过程中,会为 data 中的每一个属性生成一个主题对象 dep。

 

       在编译 HTML 的过程中,会为每个与数据绑定相关的节点生成一个订阅者 watcher,watcher 会将自己添加到相应属性的 dep 中

 

       我们已经实现:修改输入框内容 => 在事件回调函数中修改属性值 => 触发属性的 set 方法。

 

无论是angular还是vue,对于动态绑定的重新渲染,取决与model的数值变化,而react则是虚拟树的比较。我们来看看react的渲染流程。

1.创建一棵虚拟的dom树。
2.渲染到真实dom中。
3.model数据变化,告诉react重新在内存中生成新的虚拟dom树。
4.新的虚拟dom树与旧的dom树进行对比,提取两棵树不同的节点部分。
5.将变化部分,渲染到真实的dom上。

 每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。

而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并

 双向绑定和单项绑定

只有 UI控件 才存在双向,非 UI控件 只有单向

 

回到问题上,单向数据绑定和双向数据绑定的优缺点,适合什么场景?

答:
单向绑定的优点是相应的可以带来单向数据流,这样做的好处是所有状态变化都可以被记录、跟踪,状态变化通过手动调用通知,源头易追溯,没有“暗箱操作”。同时组件数据只有唯一的入口和出口,使得程序更直观更容易理解,有利于应用的可维护性。缺点则是代码量会相应的上升,数据的流转过程变长,从而出现很多类似的样板代码。同时由于对应用状态独立管理的严格要求(单一的全局store),在处理局部状态较多的场景时(如用户输入交互较多的“富表单型”应用),会显得啰嗦及繁琐。


基本上双向绑定的优缺点就是单向绑定的镜像了。优点是在表单交互较多的场景下,会简化大量业务无关的代码。缺点就是由于都是“暗箱操作”,我们无法追踪局部状态的变化(虽然大部分情况下我们并不关心),潜在的行为太多也增加了出错时 debug 的难度。同时由于组件数据变化来源入口变得可能不止一个,新手玩家很容易将数据流转方向弄得紊乱,如果再缺乏一些“管制”手段,最后就很容易因为一处错误操作造成应用雪崩。

 

 

何时触发

脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,当然Google不会这么low,angular只有在指定的事件触发时进入脏值检测,大致如下:

  • DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
  • XHR响应事件 ( $http )
  • 浏览器Location变更事件 ( $location )
  • Timer事件( $timeout , $interval )
  • 执行 $digest() 或 $apply()

数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调。

 

React 和 Vue 有许多相似之处,它们都有:

  • 使用 Virtual DOM
  • 提供了响应式(Reactive)和组件化(Composable)的视图组件。
  • 将注意力集中保持在核心库,伴随于此,有配套的路由和负责处理全局状态管理的库。

 性能渲染

 

In React, when a component’s state changes, it triggers the re-render of the entire component sub-tree, starting at that component as root.

 

To avoid unnecessary re-renders of child components, you need to implementshouldComponentUpdate everywhere and use immutable data structures. In Vue, a component’s dependencies are automatically tracked during its render, so the system knows precisely which components actually need to re-render.

翻译:

在React,当组件的state发生变化,它将触发重新呈现整个组件的子树,从该组件作为根。

为了避免不必要的子组件重新呈现,你需要去执行shouldComponentUpdate随时随地,使用不可变的数据结构,

在Vue,组件的依赖关系自动跟踪在渲染,因此系统清楚地知道哪些组件实际上需要重新呈现。

 

这意味着,未经优化的 Vue 相比未经优化的 React 要快的多。由于 Vue 改进过渲染性能,甚至全面优化过的 React 通常也会慢于开箱即用的 Vue。

 

假如你要开发一个对性能要求比较高的数据可视化或者动画的应用时,你需要了解到下面这点:在开发中,Vue 每秒最高处理 10 帧,而 React 每秒最高处理不到 1 帧。

 

这是由于 React 有大量的检查机制,这会让它提供许多有用的警告和错误提示信息。我们同样认为这些是很重要的,但是我们在实现这些检查时,也更加密切地关注了性能方面。

 

HTML&CSS

在 React 中,它们都是 JavaScript 编写的,听起来这十分简单和优雅。然而不幸的事实是,JavaScript 内的 HTML 和 CSS 会产生很多痛点。在 Vue 中我们采用 Web 技术并在其上进行扩展。接下来将通过一些实例向你展示这意味的是什么。

JSX:

 

  • 你可以使用完整的编程语言 JavaScript 功能来构建你的视图页面。
  • 工具对 JSX 的支持相比于现有可用的其他 Vue 模板还是比较先进的(比如,linting、类型检查、编辑器的自动完成)。

Vue 中,由于有时需要用这些功能,我们也提供了渲染功能 并且支持了 JSX。然而,对于大多数组件来说,渲染功能是不推荐使用了。

  • 在写模板的过程中,样式风格已定并涉及更少的功能实现。
  • 模板总是会被声明的。
  • 模板中任何 HTML 语法都是有效的。
  • 阅读起来更贴合英语(比如,for each item in items)。
  • 不需要高级版本的 JavaScript 语法,来增加可读性。 

规模

两者另一个重要差异是,Vue 的路由库和状态管理库都是由官方维护支持且与核心库同步更新的。React 则是选择把这些问题交给社区维护,因此创建了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。

本地渲染

ReactNative 能使你用相同的组件模型编写有本地渲染能力的 APP(IOS 和 Android)。能同时跨多平台开发,对开发者是非常棒的。相应地,Vue 和 Weex 会进行官方合作,Weex 是阿里的跨平台用户界面开发框架,Weex 的 JavaScript 框架运行时用的就是 Vue。这意味着在 Weex 的帮助下,你使用 Vue 语法开发的组件不仅仅可以运行在浏览器端,还能被用于开发 IOS 和 Android 上的原生应用。

posted @ 2017-03-29 11:50  Caraxiong  阅读(525)  评论(0编辑  收藏  举报