bunny笔记 | 如何同时学好Vue3 与 React18两个框架

请先看实例项目分析:Vue3 与 React 构建外卖平台项目对比分析

目录

  1. 核心语法差异
  2. 组件定义方式
  3. 状态管理
  4. 响应式原理
  5. 生命周期与副作用
  6. 事件处理
  7. 条件渲染与列表渲染
  8. 样式处理
  9. 路由管理
  10. 思维模式差异

核心语法差异

1. 模板语法 vs JSX

Vue3 - 模板语法(Template-based)

<template>
  <div class="food-item">
    <img :src="food.image" :alt="food.name" />
    <h4>{{ food.name }}</h4>
    <span>¥{{ food.price }}</span>
    <button @click="increase">+</button>
  </div>
</template>

特点:

  • 使用 HTML 模板,通过指令绑定数据
  • {{ }} 插值表达式
  • :src 属性绑定(v-bind 简写)
  • @click 事件绑定(v-on 简写)
  • 模板与逻辑分离,更接近传统 HTML

React - JSX(JavaScript XML)

function FoodItem({ food, onIncrease }) {
  return (
    <div className="food-item">
      <img src={food.image} alt={food.name} />
      <h4>{food.name}</h4>
      <span>¥{food.price}</span>
      <button onClick={onIncrease}>+</button>
    </div>
  );
}

特点:

  • JSX 是 JavaScript 的语法扩展
  • 使用 {} 嵌入 JavaScript 表达式
  • 属性使用驼峰命名(className 而非 class
  • 事件处理函数作为 props 传递
  • 模板与逻辑混合,更接近 JavaScript

核心差异:

  • Vue:声明式模板,指令系统,更接近 HTML
  • React:JSX 是 JavaScript,需要编译,更灵活但学习曲线陡

组件定义方式

2. Vue3 Composition API vs React Hooks

Vue3 - Composition API(setup 语法糖)

<script setup>
import { ref, computed } from 'vue';
import { useCartStore } from '../stores/cart';

const props = defineProps({
  food: {
    type: Object,
    required: true,
  },
  shopId: {
    type: [Number, String],
    required: true,
  },
});

const cartStore = useCartStore();

const quantity = computed(() => {
  const item = cartStore.items.find(
    (item) => item.shopId === props.shopId && item.foodId === props.food.id
  );
  return item ? item.quantity : 0;
});

const increase = () => {
  cartStore.addItem(props.shopId, props.shopName, props.food);
};
</script>

特点:

  • <script setup> 语法糖,自动暴露变量和函数
  • defineProps 定义 props,类型检查
  • 响应式数据使用 refreactive
  • 计算属性使用 computed
  • 代码组织更灵活,逻辑可复用

React - Hooks

import { useMemo } from 'react';
import { useCartStore } from '../stores/cart';

function FoodItem({ food, shopId, shopName }) {
  const cartStore = useCartStore();
  
  const quantity = useMemo(() => {
    const item = cartStore.items.find(
      (item) => item.shopId === shopId && item.foodId === food.id
    );
    return item ? item.quantity : 0;
  }, [cartStore.items, shopId, food.id]);

  const increase = () => {
    cartStore.addItem(shopId, shopName, food);
  };

  return (
    // JSX...
  );
}

特点:

  • 函数组件 + Hooks
  • Props 作为函数参数
  • useMemo 实现计算属性
  • 需要手动管理依赖数组
  • 所有逻辑都在函数体内

核心差异:

  • Vue:setup 语法糖,自动处理,更简洁
  • React:显式使用 Hooks,需要理解闭包和依赖

状态管理

3. Pinia vs Zustand/Redux

Vue3 - Pinia Store

// stores/cart.js
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';

export const useCartStore = defineStore('cart', () => {
  // 状态
  const items = ref([]);

  // 方法
  const addItem = (shopId, shopName, food) => {
    const existingItem = items.value.find(
      item => item.shopId === shopId && item.foodId === food.id
    );

    if (existingItem) {
      existingItem.quantity += 1;
    } else {
      items.value.push({
        shopId,
        shopName,
        foodId: food.id,
        foodName: food.name,
        foodPrice: food.price,
        quantity: 1
      });
    }
  };

  // 计算属性
  const totalCount = computed(() => {
    return items.value.reduce((sum, item) => sum + item.quantity, 0);
  });

  const totalPrice = computed(() => {
    return items.value.reduce((sum, item) => sum + item.foodPrice * item.quantity, 0);
  });

  return {
    items,
    addItem,
    totalCount,
    totalPrice
  };
});

使用方式:

<script setup>
import { useCartStore } from '../stores/cart';

const cartStore = useCartStore();
// 直接使用,自动响应式
console.log(cartStore.totalCount);
</script>

特点:

  • 基于 Vue 的响应式系统
  • 自动追踪依赖
  • 可以直接修改状态(通过 .value
  • 计算属性自动缓存

React - Zustand Store

// stores/cart.js
import { create } from 'zustand';

export const useCartStore = create((set, get) => ({
  // 状态
  items: [],

  // 方法
  addItem: (shopId, shopName, food) => {
    const items = get().items;
    const existingItem = items.find(
      item => item.shopId === shopId && item.foodId === food.id
    );

    if (existingItem) {
      set({
        items: items.map(item =>
          item.shopId === shopId && item.foodId === food.id
            ? { ...item, quantity: item.quantity + 1 }
            : item
        )
      });
    } else {
      set({
        items: [...items, {
          shopId,
          shopName,
          foodId: food.id,
          foodName: food.name,
          foodPrice: food.price,
          quantity: 1
        }]
      });
    }
  },

  // Getter(需要手动计算)
  getTotalCount: () => {
    return get().items.reduce((sum, item) => sum + item.quantity, 0);
  },

  getTotalPrice: () => {
    return get().items.reduce((sum, item) => sum + item.foodPrice * item.quantity, 0);
  }
}));

使用方式:

import { useCartStore } from '../stores/cart';

function Cart() {
  const items = useCartStore(state => state.items);
  const addItem = useCartStore(state => state.addItem);
  const totalCount = useCartStore(state => state.getTotalCount());
  
  // 需要手动选择需要的状态
  return <div>{totalCount}</div>;
}

特点:

  • 不可变更新模式
  • 需要手动选择订阅的状态
  • Getter 需要手动调用
  • 更符合函数式编程

核心差异:

  • Vue:响应式系统,自动追踪,直接修改
  • React:不可变更新,手动选择,函数式

响应式原理

4. Proxy vs 手动更新

Vue3 - 基于 Proxy 的响应式

// Vue3 内部实现原理(简化版)
const reactive = (target) => {
  return new Proxy(target, {
    get(target, key) {
      // 依赖收集
      track(target, key);
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      // 触发更新
      trigger(target, key);
      return true;
    }
  });
};

// 使用
const state = reactive({ count: 0 });
state.count++; // 自动触发更新

在组件中的表现:

<script setup>
const count = ref(0);
// 修改 count.value 时,所有使用 count 的地方自动更新
</script>
<template>
  <div>{{ count }}</div> <!-- 自动更新 -->
</template>

React - 手动触发更新

// React 使用 setState 触发更新
function Counter() {
  const [count, setCount] = useState(0);
  
  // 必须调用 setCount 才能触发更新
  const increment = () => {
    setCount(count + 1); // 手动触发重新渲染
  };
  
  return <div>{count}</div>;
}

核心差异:

  • Vue:自动追踪依赖,修改即更新
  • React:手动调用 setState,显式更新

生命周期与副作用

5. 生命周期对比

Vue3 - 生命周期 Hooks

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';

const shop = ref(null);
const foods = ref([]);

// 组件挂载
onMounted(() => {
  shop.value = getShopById(route.params.id);
  foods.value = getFoodsByShopId(route.params.id);
});

// 组件卸载
onUnmounted(() => {
  // 清理工作
});

// 监听变化
watch(() => route.params.id, (newId) => {
  // 路由参数变化时执行
  shop.value = getShopById(newId);
  foods.value = getFoodsByShopId(newId);
});
</script>

React - useEffect Hook

import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';

function ShopDetail() {
  const { id } = useParams();
  const [shop, setShop] = useState(null);
  const [foods, setFoods] = useState([]);

  // 组件挂载和 id 变化时执行
  useEffect(() => {
    setShop(getShopById(id));
    setFoods(getFoodsByShopId(id));
    
    // 清理函数(可选)
    return () => {
      // 清理工作
    };
  }, [id]); // 依赖数组

  return (
    // JSX...
  );
}

核心差异:

  • Vue:多个生命周期函数,职责明确
  • React:一个 useEffect 处理所有副作用,需要依赖数组

事件处理

6. 事件绑定方式

Vue3 - 指令绑定

<template>
  <button @click="handleClick">点击</button>
  <button @click.stop="handleClick">阻止冒泡</button>
  <button @click.prevent="handleSubmit">阻止默认</button>
  <input @keyup.enter="handleSearch" />
</template>

<script setup>
const handleClick = () => {
  console.log('clicked');
};
</script>

特点:

  • 指令系统,语法简洁
  • 修饰符(.stop, .prevent, .enter)方便

React - 函数传递

function Component() {
  const handleClick = (e) => {
    e.stopPropagation(); // 手动阻止冒泡
    console.log('clicked');
  };

  const handleSubmit = (e) => {
    e.preventDefault(); // 手动阻止默认
  };

  const handleKeyUp = (e) => {
    if (e.key === 'Enter') {
      handleSearch();
    }
  };

  return (
    <>
      <button onClick={handleClick}>点击</button>
      <input onKeyUp={handleKeyUp} />
    </>
  );
}

特点:

  • 标准 DOM 事件,需要手动处理
  • 更灵活但代码更多

条件渲染与列表渲染

7. 渲染语法对比

Vue3 - 指令渲染

<template>
  <!-- 条件渲染 -->
  <div v-if="shop">商家信息</div>
  <div v-else>加载中...</div>
  
  <!-- 列表渲染 -->
  <div v-for="food in foods" :key="food.id">
    {{ food.name }}
  </div>
  
  <!-- 条件显示 -->
  <span v-if="quantity > 0">{{ quantity }}</span>
</template>

React - 三元运算符和 map

function Component({ shop, foods }) {
  return (
    <>
      {/* 条件渲染 */}
      {shop ? (
        <div>商家信息</div>
      ) : (
        <div>加载中...</div>
      )}
      
      {/* 列表渲染 */}
      {foods.map(food => (
        <div key={food.id}>
          {food.name}
        </div>
      ))}
      
      {/* 条件显示 */}
      {quantity > 0 && <span>{quantity}</span>}
    </>
  );
}

核心差异:

  • Vue:指令系统,更声明式
  • React:JavaScript 表达式,更灵活

样式处理

8. 样式作用域

Vue3 - Scoped CSS

<style scoped>
.food-item {
  padding: 15px;
}
</style>

特点:

  • scoped 自动添加唯一属性选择器
  • 样式隔离,不会影响其他组件
  • 支持 CSS 变量

React - CSS Modules / Styled-components

// CSS Modules
import styles from './FoodItem.module.css';

function FoodItem() {
  return <div className={styles.foodItem}>...</div>;
}

// 或 Styled-components
import styled from 'styled-components';

const FoodItem = styled.div`
  padding: 15px;
`;

function Component() {
  return <FoodItem>...</FoodItem>;
}

特点:

  • 需要额外配置或库
  • 更灵活但需要学习成本

路由管理

9. Vue Router vs React Router

Vue3 - Vue Router

<script setup>
import { useRoute, useRouter } from 'vue-router';

const route = useRoute();
const router = useRouter();

// 获取参数
const shopId = route.params.id;

// 导航
router.push('/shop/1');
</script>

<template>
  <router-view />
</template>

React - React Router

import { useParams, useNavigate } from 'react-router-dom';

function Component() {
  const { id } = useParams();
  const navigate = useNavigate();
  
  // 导航
  navigate('/shop/1');
  
  return <div>Shop ID: {id}</div>;
}

核心差异:

  • 语法相似,但 API 略有不同
  • Vue Router 更集成,React Router 更灵活

思维模式差异

10. 编程范式对比

Vue3 - 选项式 + 声明式

思维特点:

  1. 数据驱动视图:修改数据,视图自动更新
  2. 指令系统:通过指令声明式描述行为
  3. 响应式系统:自动追踪依赖,无需手动管理
  4. 渐进式框架:可以逐步采用,学习曲线平缓

代码示例:

<script setup>
// 声明数据
const count = ref(0);

// 声明方法
const increment = () => {
  count.value++; // 修改数据,视图自动更新
};
</script>

<template>
  <!-- 声明式模板 -->
  <button @click="increment">{{ count }}</button>
</template>

React - 函数式 + 命令式

思维特点:

  1. 组件即函数:一切都是函数,函数式编程
  2. 不可变数据:通过 setState 创建新状态
  3. 显式更新:需要手动触发重新渲染
  4. JavaScript 优先:JSX 就是 JavaScript

代码示例:

function Counter() {
  // 使用 Hook 管理状态
  const [count, setCount] = useState(0);
  
  // 函数式更新
  const increment = () => {
    setCount(prev => prev + 1); // 显式更新
  };
  
  // 返回 JSX(JavaScript)
  return (
    <button onClick={increment}>{count}</button>
  );
}

实际项目对比

购物车功能实现

Vue3 实现

<!-- FoodItem.vue -->
<template>
  <div class="food-item">
    <h4>{{ food.name }}</h4>
    <span>¥{{ food.price }}</span>
    <div class="actions">
      <button v-if="quantity > 0" @click="decrease">-</button>
      <span v-if="quantity > 0">{{ quantity }}</span>
      <button @click="increase">+</button>
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue';
import { useCartStore } from '../stores/cart';

const props = defineProps({
  food: Object,
  shopId: [Number, String],
  shopName: String
});

const cartStore = useCartStore();

// 计算属性自动响应
const quantity = computed(() => {
  return cartStore.items.find(
    item => item.shopId === props.shopId && item.foodId === props.food.id
  )?.quantity || 0;
});

const increase = () => {
  cartStore.addItem(props.shopId, props.shopName, props.food);
};

const decrease = () => {
  cartStore.decreaseItem(props.shopId, props.food.id);
};
</script>

React 实现

// FoodItem.jsx
import { useMemo } from 'react';
import { useCartStore } from '../stores/cart';

function FoodItem({ food, shopId, shopName }) {
  const cartStore = useCartStore();
  
  // 需要手动管理依赖
  const quantity = useMemo(() => {
    return cartStore.items.find(
      item => item.shopId === shopId && item.foodId === food.id
    )?.quantity || 0;
  }, [cartStore.items, shopId, food.id]);

  const increase = () => {
    cartStore.addItem(shopId, shopName, food);
  };

  const decrease = () => {
    cartStore.decreaseItem(shopId, food.id);
  };

  return (
    <div className="food-item">
      <h4>{food.name}</h4>
      <span>¥{food.price}</span>
      <div className="actions">
        {quantity > 0 && <button onClick={decrease}>-</button>}
        {quantity > 0 && <span>{quantity}</span>}
        <button onClick={increase}>+</button>
      </div>
    </div>
  );
}

总结对比表

特性 Vue3 React
模板语法 HTML 模板 + 指令 JSX (JavaScript)
响应式 Proxy 自动追踪 手动 setState
状态管理 Pinia (响应式) Zustand/Redux (不可变)
组件定义 <script setup> 函数组件 + Hooks
生命周期 多个生命周期函数 useEffect + 依赖数组
事件处理 指令修饰符 标准 DOM 事件
样式 Scoped CSS CSS Modules / Styled
学习曲线 平缓 陡峭
性能 自动优化 需要手动优化
生态 Vue 生态 React 生态

选择建议

选择 Vue3 如果:

  • 团队更熟悉 HTML/CSS
  • 需要快速开发,学习曲线平缓
  • 喜欢声明式、数据驱动的开发方式
  • 需要自动响应式更新

选择 React 如果:

  • 团队更熟悉 JavaScript
  • 需要更大的生态系统和社区
  • 喜欢函数式编程
  • 需要更灵活的架构

代码示例文件

本项目的 Vue3 实现位于:

  • 组件:src/components/
  • 页面:src/views/
  • 状态管理:src/stores/cart.js
  • 路由:src/router/index.js

对应的 React 实现可以参考上述代码示例进行转换。


————————————————————————————————————————————————


那么如果想要同时学好两种框架,应该怎么做呢?同时学习 Vue3 和 React 完整指南如下(可供参考):

目录

  1. 学习策略
  2. 学习路径规划
  3. 对比学习法
  4. 实践项目建议
  5. 常见混淆点
  6. 学习资源推荐
  7. 学习时间规划
  8. 实战练习建议

学习策略

1. 先学一个,再学另一个(推荐)

为什么?

  • 避免概念混淆
  • 建立完整的知识体系
  • 更容易理解框架设计思想

建议顺序:

  1. 先学 Vue3(如果更熟悉 HTML/CSS)

    • 学习曲线平缓
    • 更接近传统 Web 开发
    • 自动响应式,减少心智负担
  2. 再学 React(如果更熟悉 JavaScript)

    • 函数式编程思维
    • 更大的生态系统
    • 更灵活但需要更多手动管理

2. 对比学习法(进阶)

适用人群:

  • 已有一定前端基础
  • 想快速掌握两个框架
  • 需要做技术选型

方法:

  • 用同一个项目分别用两个框架实现
  • 对比相同功能的实现方式
  • 理解设计理念差异

学习路径规划

阶段一:基础语法(2-3周)

Vue3 学习重点

  1. 模板语法

    • 插值表达式 {{ }}
    • 指令系统(v-if, v-for, v-bind, v-on)
    • 事件处理
  2. 组件基础

    • 单文件组件(SFC)
    • Props 和 Emits
    • <script setup> 语法
  3. 响应式数据

    • ref()reactive()
    • computed() 计算属性
    • watch() 监听器

实践项目: Todo 列表应用

React 学习重点

  1. JSX 语法

    • JSX 基础
    • 表达式嵌入 {}
    • 条件渲染和列表渲染
  2. 组件基础

    • 函数组件
    • Props 传递
    • 组件组合
  3. Hooks 基础

    • useState 状态管理
    • useEffect 副作用
    • useMemouseCallback

实践项目: Todo 列表应用(用 React 重写)

阶段二:状态管理(2-3周)

Vue3 - Pinia

// 学习重点
- defineStore 定义 store
- ref/reactive 响应式状态
- computed 计算属性
- actions 方法定义

实践: 购物车功能

React - Zustand/Redux

// 学习重点
- create store
- 不可变更新模式
- 状态选择器
- 中间件使用

实践: 购物车功能(用 React 重写)

阶段三:路由管理(1-2周)

Vue3 - Vue Router

// 学习重点
- 路由配置
- useRoute / useRouter
- 路由守卫
- 动态路由

React - React Router

// 学习重点
- Routes / Route
- useParams / useNavigate
- 路由守卫
- 嵌套路由

实践: 多页面应用(首页、列表、详情)

阶段四:高级特性(3-4周)

Vue3

  • 组件通信(provide/inject)
  • 插槽(Slots)
  • 过渡动画
  • 自定义指令
  • Teleport

React

  • Context API
  • Render Props / HOC
  • 错误边界
  • Suspense
  • Portal

阶段五:生态工具(2-3周)

Vue3 生态

  • Vite 构建工具
  • VueUse 工具库
  • Element Plus / Ant Design Vue
  • Pinia 状态管理

React 生态

  • Create React App / Vite
  • React Query
  • Material-UI / Ant Design
  • Redux Toolkit / Zustand

对比学习法

方法一:功能对比表

创建一个对比表,记录相同功能在两个框架中的实现:

功能 Vue3 实现 React 实现 差异点
状态管理 ref(0) useState(0) 响应式 vs 不可变
计算属性 computed() useMemo() 自动依赖 vs 手动依赖
监听变化 watch() useEffect() 声明式 vs 命令式
事件处理 @click onClick 指令 vs 属性

方法二:项目对比实现

步骤:

  1. 选择一个项目(如:外卖平台)
  2. 先用 Vue3 实现完整功能
  3. 再用 React 实现相同功能
  4. 对比代码差异和实现思路

对比维度:

  • 代码量
  • 可读性
  • 性能
  • 开发体验

方法三:概念映射

建立概念映射关系,帮助记忆:

Vue3              →  React
─────────────────────────────
ref()             →  useState()
computed()        →  useMemo()
watch()           →  useEffect()
v-if              →  三元运算符
v-for             →  map()
@click            →  onClick
:class            →  className
<script setup>    →  函数组件

实践项目建议

初级项目(建议顺序)

1. Todo 应用

Vue3 版本:

  • 学习:响应式数据、事件处理、列表渲染
  • 重点:ref, v-for, @click

React 版本:

  • 学习:useState, map, 事件处理
  • 重点:状态更新、不可变数据

2. 计数器应用

对比点:

  • 状态更新方式
  • 事件处理方式
  • 响应式机制

3. 天气查询应用

学习点:

  • API 调用
  • 异步处理
  • 错误处理

中级项目

4. 购物车应用(本项目)

Vue3 实现重点:

  • Pinia 状态管理
  • 计算属性
  • 组件通信

React 实现重点:

  • Zustand/Redux 状态管理
  • useMemo 优化
  • Context API

5. 博客系统

学习点:

  • 路由管理
  • 数据获取
  • 表单处理

高级项目

6. 实时聊天应用

学习点:

  • WebSocket
  • 实时更新
  • 性能优化

7. 管理后台系统

学习点:

  • 复杂状态管理
  • 权限控制
  • 数据可视化

常见混淆点

1. 响应式更新

❌ 错误理解

// Vue3 - 错误
const count = 0; // 不是响应式的
count++; // 不会触发更新

// React - 错误
const [count, setCount] = useState(0);
count++; // 不会触发更新,必须用 setCount

✅ 正确理解

// Vue3 - 正确
const count = ref(0);
count.value++; // 自动触发更新

// React - 正确
const [count, setCount] = useState(0);
setCount(count + 1); // 手动触发更新

2. 列表渲染 Key

Vue3

<div v-for="item in list" :key="item.id">
  {{ item.name }}
</div>

React

{list.map(item => (
  <div key={item.id}>
    {item.name}
  </div>
))}

共同点: 都需要 key,用于优化渲染性能

3. 条件渲染

Vue3

<div v-if="isVisible">显示</div>
<div v-show="isVisible">显示(CSS控制)</div>

React

{isVisible && <div>显示</div>}
{isVisible ? <div>显示</div> : null}

区别:

  • Vue: v-if 条件渲染,v-show CSS 控制
  • React: 都是条件渲染,需要 CSS 控制显示隐藏

4. 事件处理

Vue3

<button @click="handleClick">点击</button>
<button @click.stop="handleClick">阻止冒泡</button>

React

<button onClick={handleClick}>点击</button>
<button onClick={(e) => {
  e.stopPropagation();
  handleClick();
}}>阻止冒泡</button>

区别:

  • Vue: 指令修饰符,语法简洁
  • React: 标准 DOM 事件,需要手动处理

5. 样式处理

Vue3

<style scoped>
.component {
  color: red;
}
</style>

React

// CSS Modules
import styles from './Component.module.css';
<div className={styles.component}>内容</div>

// 或 Styled-components
const Component = styled.div`
  color: red;
`;

区别:

  • Vue: 内置 scoped,开箱即用
  • React: 需要配置或使用第三方库

学习资源推荐

Vue3 学习资源

官方文档

推荐教程

  1. Vue3 官方教程 - 最权威,最全面
  2. Vue Mastery - 视频教程,循序渐进
  3. Vue School - 系统化课程

实战项目

React 学习资源

官方文档

推荐教程

  1. React 官方教程 - 官方推荐,质量高
  2. React 官方 Beta 文档 - 最新 Hooks 教程
  3. Epic React - 付费但质量极高

实战项目

对比学习建议

找一些相同功能的项目做对比学习,或者通过一些现成的学习对比网站查阅分析,知晓其原理差异加上手动实操


学习时间规划

方案一:循序渐进(推荐)

总时长:10-12 周

阶段 时间 Vue3 React 重点
第1-2周 基础语法 - 先掌握一个框架
第3-4周 状态管理 - 深入理解响应式
第5-6周 路由+项目 - 完整项目实践
第7-8周 React基础 - 学习第二个框架
第9-10周 React进阶 - 状态管理+路由
第11-12周 对比学习 对比实现相同项目

方案二:并行学习(进阶)

总时长:8-10 周

周次 Vue3 React 对比项目
第1-2周 基础语法 基础语法 Todo 应用
第3-4周 状态管理 Hooks 计数器应用
第5-6周 路由 路由 多页面应用
第7-8周 项目实战 项目实战 购物车应用
第9-10周 高级特性 高级特性 完整项目对比

注意: 并行学习容易混淆,建议有一定基础后再采用


实战练习建议

练习 1:基础语法对比

任务: 实现一个简单的计数器

Vue3 版本:

<template>
  <div>
    <p>计数:{{ count }}</p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

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

const count = ref(0);

const increment = () => {
  count.value++;
};

const decrement = () => {
  count.value--;
};
</script>

React 版本:

import { useState } from 'react';

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

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <p>计数:{count}</p>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </div>
  );
}

对比点:

  • 状态定义方式
  • 更新方式
  • 模板语法

练习 2:列表渲染对比

任务: 实现商品列表

Vue3 版本:

<template>
  <div v-for="food in foods" :key="food.id">
    <h3>{{ food.name }}</h3>
    <p>¥{{ food.price }}</p>
  </div>
</template>

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

const foods = ref([
  { id: 1, name: '汉堡', price: 20 },
  { id: 2, name: '薯条', price: 15 }
]);
</script>

React 版本:

import { useState } from 'react';

function FoodList() {
  const [foods] = useState([
    { id: 1, name: '汉堡', price: 20 },
    { id: 2, name: '薯条', price: 15 }
  ]);

  return (
    <>
      {foods.map(food => (
        <div key={food.id}>
          <h3>{food.name}</h3>
          <p>¥{food.price}</p>
        </div>
      ))}
    </>
  );
}

练习 3:状态管理对比

任务: 实现购物车功能

Vue3 + Pinia:

// stores/cart.js
export const useCartStore = defineStore('cart', () => {
  const items = ref([]);
  
  const addItem = (food) => {
    items.value.push(food);
  };
  
  const totalPrice = computed(() => {
    return items.value.reduce((sum, item) => sum + item.price, 0);
  });
  
  return { items, addItem, totalPrice };
});

React + Zustand:

// stores/cart.js
export const useCartStore = create((set, get) => ({
  items: [],
  
  addItem: (food) => {
    set({ items: [...get().items, food] });
  },
  
  getTotalPrice: () => {
    return get().items.reduce((sum, item) => sum + item.price, 0);
  }
}));

学习技巧

1. 建立知识地图

创建一个思维导图,记录两个框架的:

  • 核心概念
  • API 对比
  • 使用场景
  • 最佳实践

2. 做笔记对比

每次学习新概念时,记录:

  • Vue3 的实现方式
  • React 的实现方式
  • 各自的优缺点
  • 适用场景

3. 实践驱动学习

  • 不要只看文档,要动手实践
  • 用两个框架实现相同功能
  • 对比代码差异和性能

4. 加入社区

  • Vue 中文社区
  • React 中文社区
  • GitHub 关注相关项目
  • 参与开源项目

5. 定期复习

  • 每周回顾学习内容
  • 对比两个框架的差异
  • 总结最佳实践

常见问题 FAQ

Q1: 先学哪个框架?

  • 如果更熟悉 HTML/CSS → 先学 Vue3
  • 如果更熟悉 JavaScript → 先学 React
  • 如果零基础 → 建议先学 Vue3(学习曲线平缓)

Q2: 会不会混淆两个框架?

  • 初期可能会混淆,这是正常的
  • 通过对比学习,建立清晰的概念映射
  • 多实践,形成肌肉记忆

Q3: 需要学到什么程度?

  • 基础: 能独立完成中小型项目
  • 进阶: 理解框架原理,能优化性能
  • 高级: 能根据项目需求选择合适框架

Q4: 如何选择使用哪个框架?

  • Vue3: 快速开发、团队熟悉 HTML、需要自动响应式
  • React: 大型项目、需要灵活架构、团队熟悉 JavaScript

Q5: 学习时间不够怎么办?

  • 优先掌握一个框架到熟练程度
  • 另一个框架了解核心概念即可
  • 根据实际项目需求深入学习

学习检查清单

Vue3 掌握程度

  • 理解模板语法和指令系统
  • 掌握 Composition API
  • 理解响应式原理(ref, reactive)
  • 会使用 Pinia 进行状态管理
  • 掌握 Vue Router 路由管理
  • 能独立完成中等复杂度项目

React 掌握程度

  • 理解 JSX 语法
  • 掌握 Hooks(useState, useEffect 等)
  • 理解函数式组件
  • 会使用 Zustand/Redux 进行状态管理
  • 掌握 React Router 路由管理
  • 能独立完成中等复杂度项目

对比理解

  • 能说出两个框架的核心差异
  • 能根据场景选择合适框架
  • 能用两个框架实现相同功能
  • 理解各自的优缺点

总结

同时学习 Vue3 和 React 的关键:

  1. 循序渐进 - 先掌握一个,再学另一个
  2. 对比学习 - 用相同项目对比实现方式
  3. 实践为主 - 多写代码,少看文档
  4. 建立映射 - 理解概念对应关系
  5. 持续练习 - 定期复习和实战

记住:框架只是工具,核心是理解前端开发思想。 掌握了两个框架后,你会对前端开发有更深入的理解。


END

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容