面试官:说下 Vue 和 React 数据驱动原理的区别吧!

开发 前端
Vue 的响应式系统可以自动追踪数据变化,并只对发生变化的数据进行更新。通过响应式系统,Vue 可以做到在数据层发生变化时,自动将变化反映到视图层,而无需额外的 diff 比较。

Hello,大家好,我是 Sunday。

昨天有位同学面试的时候被问到了:“说下 Vue 和 React 数据驱动原理的区别”。

所以今天咱们把这个问题说一下。

回答这种问题,我们可以采取 总分总 的方式,从以下四个层面进行描述:

  1. 数据驱动
  2. 数据追踪的机制
  3. 数据流控制
  4. 数据更新机制

答案

React 和 Vue 都基于数据驱动的理念,也就是:当数据发生变化时,视图自动更新。但是,他们在数据驱动的实现方式和概念是不同的。大致可以分为 4 点去说:

1. 数据驱动概念的核心思想

  • React:React 的数据驱动依赖于不可变数据和单向数据流的思想。React 组件的状态(state)是通过不可变的数据更新触发重新渲染。组件的更新是通过“重新渲染整个组件树”,而不是直接操作 DOM 元素。
  • Vue:Vue 则采用响应式数据系统,通过 Proxy(Vue 3)或 Object.defineProperty(Vue 2)来追踪数据的变化,自动更新视图。Vue 的数据驱动模型更接近于“声明式”编程,开发者只需要修改数据,Vue 的响应式系统会自动处理 DOM 更新。

2. 数据变化的追踪机制

React: 手动触发更新

  • 在 React 中,数据变化通过显式地更新 state 来驱动视图更新。例如,使用 this.setState 或 useState 钩子来改变组件的状态,然后 React 会根据更新后的状态重新渲染组件。
  • 不可变数据:React 强调数据不可变,任何对数据的修改都需要返回一个新的对象,以便 React 识别状态是否发生变化。React 通过浅比较来判断组件是否需要更新。

示例:

function MyComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>Increase</button>
    </div>
  );
}

只有通过 setCount 才会触发组件重新渲染。

Vue: 自动追踪数据变化

  • Vue 的数据变化是自动追踪的。当数据被修改时,Vue 的响应式系统会立即追踪到这个变化,并自动更新相应的视图。Vue 的响应式系统会侦听对象属性的变化,通过 Proxy(Vue 3)或 Object.defineProperty(Vue 2)来劫持数据访问和修改,从而实现数据与视图的双向绑定。
  • 这种机制让 Vue 的开发体验更加简洁,开发者不需要手动触发视图更新,只要修改数据,视图就会自动反映最新状态。

示例:

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increase">Increase</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increase() {
      this.count += 1;
    },
  },
};
</script>

在 Vue 中,修改 this.count 就会触发视图更新,无需显式调用渲染函数。

3. 数据流的控制

React: 单向数据流

  • React 的数据流是单向的,即数据从父组件流向子组件,通过 props 进行传递。子组件不能直接修改父组件的数据,而是通过回调函数让父组件更新状态,这种设计简化了数据流的管理,特别是在复杂应用中,保证了数据流的可控性和可预测性。
  • 不可变性:React 提倡数据不可变,组件状态或 props 发生变化时,会创建新的对象,并通过 setState 或 useState 重新渲染组件。

示例:

function Parent() {
  const [count, setCount] = useState(0);

  return <Child count={count} onIncrease={() => setCount(count + 1)} />;
}

function Child({ count, onIncrease }) {
  return (
    <div>
      <p>{count}</p>
      <button onClick={onIncrease}>Increase</button>
    </div>
  );
}

数据从 Parent 流向 Child,更新通过回调函数从 Child 传回 Parent。

Vue: 双向数据绑定和单向数据流

  • Vue 提供了类似 React 的单向数据流,通过 props 将数据从父组件传递到子组件。子组件可以发出事件(如 $emit)通知父组件进行数据更新。
  • 但是,Vue 还支持双向数据绑定,尤其是在表单元素上,Vue 提供了 v-model 指令,可以实现数据的双向绑定——即视图中的数据变化会直接更新模型,模型数据变化也会自动反映在视图上。这使得处理表单、输入等场景更加简单。

示例:单向数据流

<template>
  <Child :count="count" @increase="increaseCount" />
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increaseCount() {
      this.count += 1;
    },
  },
};
</script>

示例:双向数据绑定

<template>
  <input v-model="name" />
</template>

<script>
export default {
  data() {
    return {
      name: '',
    };
  },
};
</script>

通过 v-model,name 的变化会自动更新输入框的内容,输入框内容变化也会更新 name。

4. 数据更新与性能优化

React: 虚拟 DOM + Reconciliation

  • React 使用虚拟 DOM来管理视图的更新。当组件的状态或 props 发生变化时,React 会重新渲染虚拟 DOM 树,并将其与之前的虚拟 DOM 进行对比(即 diff 过程)。React 通过 diff 算法找出变化的部分,并将这些部分应用到真实 DOM 中。
  • 不可变数据:由于 React 使用不可变数据,React 可以通过浅比较来判断数据是否发生了变化,从而减少不必要的更新。

Vue: 响应式系统 + 模板编译优化

  • Vue 的响应式系统可以自动追踪数据变化,并只对发生变化的数据进行更新。通过响应式系统,Vue 可以做到在数据层发生变化时,自动将变化反映到视图层,而无需额外的 diff 比较。
  • 模板编译优化:Vue 在编译阶段对模板进行分析,提取出静态和动态部分,从而优化渲染时的性能。静态内容只渲染一次,而动态内容则通过响应式系统高效更新。

5. 总结

特性

React

Vue

数据追踪机制

显式通过 setStateuseState 触发更新

自动追踪数据变化,基于 Proxy 实现响应式更新

数据流模式

单向数据流,父组件通过 props 传递数据

单向数据流 + 双向数据绑定,v-model 支持

数据更新机制

不可变数据,浅比较优化性能

响应式系统,自动侦听数据变化

视图更新策略

虚拟 DOM + diff 对比,找到最小更新集

模板编译优化 + 响应式系统

性能优化手段

应用不可变数据、memouseMemo 等手段

静态内容提升、Patch Flags(Vue 3)优化更新

Vue 的数据驱动更加自动化和“声明式”,而 React 则更依赖开发者显式地控制状态和数据流

责任编辑:武晓燕 来源: 程序员Sunday
相关推荐

2020-11-24 07:48:32

React

2021-07-01 07:51:45

React事件绑定

2022-03-21 09:05:18

volatileCPUJava

2021-05-10 08:01:12

BeanFactoryFactoryBean容器

2022-09-13 14:44:40

HashMap哈希表红黑树

2020-10-23 09:26:57

React-Redux

2023-12-27 18:16:39

MVCC隔离级别幻读

2024-11-19 15:13:02

2020-12-31 07:34:04

Redis数据宕机

2021-05-12 08:20:53

开发

2021-07-02 07:06:20

React组件方式

2020-12-09 10:29:53

SSH加密数据安全

2024-08-22 10:39:50

@Async注解代理

2024-03-05 10:33:39

AOPSpring编程

2024-04-03 15:33:04

JWTSession传输信息

2024-09-19 08:42:43

2021-06-30 07:19:36

React事件机制

2023-02-17 08:10:24

2021-06-29 09:47:34

ReactSetState机制

2021-07-06 07:27:45

React元素属性
点赞
收藏

51CTO技术栈公众号