Vue中的单向数据流和双向绑定

vue既然是单向数据流,又是MVVM框架,那么,这之间有没有什么冲突。

单向数据流

单向数据流指只能从一个方向来修改状态。

在这里插入图片描述

state:驱动应用的数据源。view:以声明方式将 state 映射到视图 。 actions:响应在 view 上的用户输入导致的状态变化。

单向数据流过程:

简单的单向数据流(unidirectional data flow)是指用户访问View,View发出用户交互的Action,在Action里对state进行相应更新。state更新后会触发View更新页面的过程。这样数据总是清晰的单向进行流动,便于维护并且可以预测。

特点:

(1) 所有状态的改变可记录、可跟踪,源头易追溯;
(2) 所有数据只有一份,组件数据只有唯一的入口和出口,使得程序更直观更容易理解,有利于应用的可维护性;
(3) 一旦数据变化,就去更新页面(data-页面),但是没有(页面-data);
(4) 如果用户在页面上做了变动,那么就手动收集起来(双向是自动),合并到原有的数据中。

组件之间的单项数据流:

父组件中的数据可以通过props流动到子组件中,并且当父组件中的数据发生改变的时候,子组件会自动接收到这个修改后的数据并且更新页面中的内容。

所以,数据一般是由父组件提供的,当父组件中的数据发生了改变,子组件就会自动接收到这个数据的变化,从而更新子组件。

但是反过来则不行,这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

注意:

1、数据从父组件流向(传递)给子组件,只能单向绑定。

2、在子组件内部不应该修改父组件传递过来的数据。
在这里插入图片描述
优点:

1.所有状态的改变可记录、可跟踪,源头易追溯;
2.所有数据只有一份,组件数据只有唯一的入口和出口,使得程序更直观更容易理解,有利于应用的可维护性;
3.一旦数据变化,就去更新页面(data-页面),但是没有(页面-data);
4.如果用户在页面上做了变动,那么就手动收集起来(双向是自动),合并到原有的数据中。

缺点:

HTML 代码渲染完成,无法改变,有新数据,就须把旧 HTML 代码去掉,整合新数据和模板重新渲染;
代码量上升,数据流转过程变长,出现很多类似的样板代码;
同时由于对应用状态独立管理的严格要求(单一的全局 store),在处理局部状态较多的场景时(如用户输入交互较多的“富表单型”应用),会显得啰嗦及繁琐。

vue的双向绑定

主要是由MVVM框架实现,在Vue中主要由三个部分组成,View、ViewModel和Model组成,其中View和Model不能直接进行通信,他们要通过中间件ViewModel来进行。例如,当Model部分数据发生改变时,由于vue中Data Binding将底层数据和Dom层进行了绑定,ViewModel通知View层更新视图;当在视图 View数据发生变化也会同步到Model中。View和Model之间的同步完全是自动的,不需要人手动的操作DOM。
在这里插入图片描述
优点

1.用户在视图上的修改会自动同步到数据模型中去,数据模型中值的变化也会立刻同步到视图中去;
2.无需进行和单向数据绑定的那些相关操作;
3.在表单交互较多的场景下,会简化大量业务无关的代码。

缺点:

1.无法追踪局部状态的变化;

2.“暗箱操作”,增加了出错时 debug 的难度;

4.由于组件数据变化来源入口变得可能不止一个,数据流转方向易紊乱,若再缺乏“管制”手段,血崩。

vue既然是单向数据流,又是MVVM框架,那么,这之间有没有什么冲突?

即两者并不互斥, 在全局性数据流使用单项,方便跟踪; 局部性数据流使用双向,简单易操作。

对于非 UI 控件来说,不存在双向,只有单向。只有 UI 控件才有双向的问题。单向绑定使得数据流也是单向的,对于复杂应用来说这是实施统一的状态管理(如 Vuex)的前提。双向绑定在一些需要实时反应用户输入的场合会非常方便(比如表单提交)。但通常认为复杂应用中这种便利比不上引入状态管理带来的优势。

对于 Vue 中的 v-model 来说,他是一个语法糖,利用 bind 语法与事件来实现数据与视图之间的绑定。
v-model 可以理解下面这样的代码(不完全一致)

实质上也是单向数据流在加上用户的操作事件来实现双向数据绑定。

搞清楚双向绑定的实现原理之后,可以看到双绑跟单向绑定之间的差异只在于,双向绑定把数据变更的操作隐藏在框架内部,调用者并不会直接感知。

单向绑定相应地使得数据流也是单向的,而在践行单向数据流的 Vuex 中,其实不过是在全局搞了一个单例的事件分发器 (dispatcher),开发者必须显式地通过这个统一的事件机制做数据变更通知。其实这种方式跟框架对 UI 控件 上实现双向绑定的方式是一样的。底层都是事件机制。试想一下,假设在双向绑定的应用中,我们有办法修改框架对 UI 控件 自动绑定的事件 listener 或 数据 watcher,然后加上类似 dispatcher 的逻辑,双向绑定背后的状态变化我们一样可以管理起来,一样可以享用单向数据流才有的收益。

发布了83 篇原创文章 · 获赞 337 · 访问量 56万+

猜你喜欢

转载自blog.csdn.net/liuyifeng0000/article/details/104976813