Vue 与 React 对比

从响应式、模板语法、数据流三个维度对比 Vue 和 React

问题

Vue 与 React 有哪些主要区别?从响应式 vs 不可变数据、模板 vs JSX、双向流 vs 单向流三个方面说明。

解答

1. 响应式 vs 不可变数据

Vue:响应式数据

Vue 通过 Proxy(Vue 3)或 Object.defineProperty(Vue 2)实现数据劫持,直接修改数据即可触发更新。

// Vue 3 Composition API
import { ref, reactive } from 'vue'

// 基本类型用 ref
const count = ref(0)
count.value++ // 直接修改,自动触发更新

// 对象用 reactive
const state = reactive({
  name: 'Tom',
  age: 18
})
state.age = 19 // 直接修改属性,自动触发更新

React:不可变数据

React 要求通过 setState 或 useState 返回新对象来触发更新,不能直接修改原数据。

// React Hooks
import { useState } from 'react'

function Counter() {
  const [count, setCount] = useState(0)
  
  // 必须调用 setter 函数
  const increment = () => setCount(count + 1)
  
  const [user, setUser] = useState({ name: 'Tom', age: 18 })
  
  // 必须返回新对象,不能直接修改 user.age
  const updateAge = () => setUser({ ...user, age: 19 })
  
  return <button onClick={increment}>{count}</button>
}

2. 模板 vs JSX

Vue:模板语法

Vue 使用基于 HTML 的模板语法,通过指令实现逻辑。

<template>
  <div>
    <!-- 条件渲染 -->
    <p v-if="show">显示内容</p>
    
    <!-- 列表渲染 -->
    <ul>
      <li v-for="item in list" :key="item.id">
        {{ item.name }}
      </li>
    </ul>
    
    <!-- 事件绑定 -->
    <button @click="handleClick">点击</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const show = ref(true)
const list = ref([
  { id: 1, name: 'Apple' },
  { id: 2, name: 'Banana' }
])

const handleClick = () => {
  show.value = !show.value
}
</script>

React:JSX

React 使用 JSX,本质是 JavaScript,用 JS 表达式实现逻辑。

function App() {
  const [show, setShow] = useState(true)
  const list = [
    { id: 1, name: 'Apple' },
    { id: 2, name: 'Banana' }
  ]

  return (
    <div>
      {/* 条件渲染:三元或 && */}
      {show && <p>显示内容</p>}
      
      {/* 列表渲染:map */}
      <ul>
        {list.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
      
      {/* 事件绑定 */}
      <button onClick={() => setShow(!show)}>点击</button>
    </div>
  )
}

3. 双向绑定 vs 单向数据流

Vue:支持双向绑定

Vue 通过 v-model 实现表单双向绑定。

<template>
  <!-- v-model 是语法糖,等价于 :value + @input -->
  <input v-model="message" />
  <p>{{ message }}</p>
  
  <!-- 组件上使用 v-model -->
  <CustomInput v-model="text" />
</template>

<script setup>
import { ref } from 'vue'

const message = ref('')
const text = ref('')
</script>

React:单向数据流

React 需要手动实现”双向绑定”,数据始终单向流动。

function App() {
  const [message, setMessage] = useState('')

  return (
    <div>
      {/* 手动绑定 value 和 onChange */}
      <input 
        value={message} 
        onChange={e => setMessage(e.target.value)} 
      />
      <p>{message}</p>
    </div>
  )
}

对比总结表

特性VueReact
数据更新直接修改,自动追踪返回新值,手动触发
视图语法模板 + 指令JSX(JavaScript)
表单处理v-model 双向绑定受控组件,单向流
学习曲线较平缓需要熟悉函数式思想
心智模型可变数据不可变数据

关键点

  • 响应式原理不同:Vue 自动追踪依赖,React 依赖不可变数据和手动 setState
  • 模板 vs JSX:Vue 模板更接近 HTML,React JSX 更灵活(纯 JS)
  • v-model 是语法糖:本质是 :value + @update:modelValue 的组合
  • React 单向流更可预测:数据流向清晰,便于调试和追踪
  • 选择依据:Vue 上手快、开发效率高;React 灵活性强、生态更大