1. 简单对比
Vue是渐进式框架,提供开箱即用的完整方案。它的模板语法直观,响应式系统自动追踪依赖,上手简单。Vue 3的Composition API也让复杂逻辑组织更清晰。
React是UI库,专注于视图层。它用JSX将HTML和JavaScript结合,提供最大的灵活性。React的Hooks和函数组件让逻辑复用更方便,但需要自己选择路由、状态管理等生态。
1-1、相同点
- 都有组件化思想
- 都支持服务器端渲染 React(Next.js)、 Vue(Nuxt.js)
- 都有Virtual DOM(虚拟DOM)
- 都是数据驱动视图
- 都有支持
native的方案:Vue的weex、React的React native - 都有自己的构建工具:Vue的vue-cli、React的Create React App
1-2、不同点
- Vue用模板,直观易上手;React用JSX,灵活强大
- Vue自动追踪依赖(修改响应式数据时,Vue能自动知道哪些组件依赖这个数据,并触发更新),React需要手动触发更新(状态变化必须通过setState或useState的setter函数)
- Vue官方提供完整方案(状态管理是'官方套餐'模式。Vue 2有Vuex,Vue 3推荐Pinia),React需要选择社区方案(React只提供useState、useReducer、Context等基础能力,复杂状态管理交给社区。有Redux(最流行)、MobX(响应式)、Zustand(轻量)、Recoil(原子化)等几十种选择)
2. 基础组件定义
Vue2 (options API)
export default {
name: 'MyComponent',
props: ['title'],
data() {
return { count: 0 }
},
methods: {
increment() {
this.count++
}
}
}
Vue3 (conponents API)
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
}
React (class组件)
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
increment = () => {
this.setState({ count: this.state.count + 1 })
}
}
React (函数组件)
function MyComponent() {
const [count, setCount] = useState(0)
const increment = () => setCount(c => c + 1)
return /* JSX */
}
3. 生命周期
| Vue 生命周期钩子 | React 类组件生命周期 | React Hooks 等效实现 | 触发时机说明 |
|---|---|---|---|
beforeCreate | - | - | 实例初始化前,data/methods 不可用 |
created | - | useState 初始化 | 实例创建完成,可访问 data/methods |
beforeMount | componentWillMount | - | 模板编译完成,DOM 挂载前 |
mounted | componentDidMount | useEffect(() => {}, []) | DOM 挂载完成 |
beforeUpdate | componentWillUpdate | - | 数据变化后,DOM 更新前 |
updated | componentDidUpdate | useEffect(() => {}) | DOM 更新完成后 |
beforeUnmount (Vue3) | componentWillUnmount | useEffect(() => { return cleanup }) | 实例销毁前 |
unmounted (Vue3) | - | cleanup 函数执行 | 实例已销毁 |
activated | - | - | keep-alive 组件激活时 |
deactivated | - | - | keep-alive 组件停用时 |
4. 计算属性(computed) vs useMemo
Vue (computed)
// 选项式
computed: {
doubled() {
return this.count * 2
}
}
// 组合式
const doubled = computed(() => count.value * 2)
React (useMemo)
const doubled = useMemo(() => count * 2, [count])
5. 监听(watch) vs useEffect
Vue (watch)
// vue2
export default {
data() {
return {
count: 0,
user: { name: 'Alice', age: 25 }
}
},
watch: {
// 基本用法
count(newVal, oldVal) {
console.log(`count changed: ${oldVal} -> ${newVal}`)
}
}
}
// vue3
// 组合式 API
import { ref, watch, reactive } from 'vue'
export default {
setup() {
const count = ref(0)
const user = reactive({ name: 'Alice', age: 25 })
// 监听 ref
watch(count, (newVal, oldVal) => {
console.log(`count changed: ${oldVal} -> ${newVal}`)
}, { immediate: true })
// 监听 reactive 对象(自动深度监听)
watch(
() => ({ ...user }), // 解构避免直接监听 reactive
(newVal) => {
console.log('user changed:', newVal)
}
)
// 监听特定属性
watch(
() => user.name,
(newVal) => {
console.log('name changed:', newVal)
}
)
// 同时监听多个值
watch([count, () => user.name], ([newCount, newName]) => {
console.log(`Multiple: count=${newCount}, name=${newName}`)
})
return { count, user }
}
}
React (useEffect)
// 最常用方式
import { useState, useEffect } from 'react';
function Component() {
const [count, setCount] = useState(0);
const [double, setDouble] = useState(0);
// 监听 count 变化(等效 Vue 的 watch)
useEffect(() => {
setDouble(count * 2);
console.log('count changed:', count);
}, [count]); // 依赖数组,只有 count 变化时才会重新执行
return <button onClick={() => setCount(c => c + 1)}>{count} x 2 = {double}</button>;
}
// 使用第三方库 ahooks
import { useWatch } from 'ahooks';
useWatch(count, (newVal, oldVal) => {
console.log('count changed', oldVal, '->', newVal);
});
6. Vue和React的diff对比
Diff原理:
Vue2 是全量 Diff,采用的思想是同级比较、深度优先、双端遍历。
Vue3 是静态标记 + 非全量 Diff
React 是 同级比较、深度优先、组件类型一致性、key 属性优化
vue2采用双指针,从两头向中间进行遍历
react 采用单指针从左向右进行遍历
| 特性维度 | Vue 2 Diff 算法 | Vue 3 Diff 算法 | React Diff 算法 |
|---|---|---|---|
| 算法类型 | 双端比较(两端向中间) | 快速Diff(动态规划+最长递增子序列) | 递归协调(同层级比较) |
| 时间复杂度 | O(n) | O(n)常数更小 | O(n³)优化到O(n) |
| 比较策略 | 同级比较 | 同层级比较+预处理+最长递增子序列 | 同级比较 |
| Key依赖 | 重要但不是必需 | 关键优化依据,LIS算法基础 | 必需,否则性能差 |
| 更新粒度 | 组件级别 | 组件级别+块树(Block Tree) | 组件级别+Fiber架构 |
| DOM移动优化 | 较差,移动成本高 | 最优,最小化移动次数 | 一般,常删除重建 |
| 静态内容处理 | 不优化,每次都比较 | 静态提升,跳过diff | 不优化,每次都比较 |
7.Vue 和 React 全局变量方案对比
React 的全局变量方案
(1) Context API(官方推荐)
// 1. 创建 Context
const UserContext = React.createContext();
// 2. 提供全局变量(在顶层组件)
function App() {
const [user, setUser] = React.useState({ name: "John", age: 25 });
return (
<UserContext.Provider value={{ user, setUser }}>
<ChildComponent />
</UserContext.Provider>
);
}
// 3. 在子组件中使用
function ChildComponent() {
const { user, setUser } = React.useContext(UserContext);
return <div>Hello, {user.name}!</div>;
}
(2) Redux(适用于复杂状态管理)
Vue 的全局变量方案
(1) Provide/Inject(适用于简单全局变量)
// App.vue
<script>
import { provide, ref } from "vue";
export default {
setup() {
const user = ref({ name: "John" });
provide("user", user); // 提供全局变量
},
};
</script>
// ChildComponent.vue
<script>
import { inject } from "vue";
export default {
setup() {
const user = inject("user"); // 获取全局变量
return { user };
},
};
</script>
(2) Vuex(官方状态管理库)
