最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React轉(zhuǎn)Vue3的避坑指南

 更新時(shí)間:2026年04月21日 09:44:18   作者:斌味代碼  
從 React 轉(zhuǎn) Vue3,相信很多前端工程師都有過這個(gè)經(jīng)歷,本文專門針對(duì) React 開發(fā)者視角,對(duì)照講解 Vue3 的核心概念,幫助你快速建立 Vue3 思維模型,少走彎路,需要的朋友可以參考下

一、前言

從 React 轉(zhuǎn) Vue3,相信很多前端工程師都有過這個(gè)經(jīng)歷。兩者雖然都致力于"構(gòu)建用戶界面",但設(shè)計(jì)思想、API 風(fēng)格、狀態(tài)管理機(jī)制都有本質(zhì)差異。本文專門針對(duì) React 開發(fā)者視角,對(duì)照講解 Vue3 的核心概念,幫助你快速建立 Vue3 思維模型,少走彎路。

本文重點(diǎn)覆蓋:響應(yīng)式系統(tǒng)對(duì)比、組件寫法差異、Hooks 與 Composition API 的對(duì)照、狀態(tài)管理方案、以及常見思維誤區(qū)和正確做法。每個(gè)知識(shí)點(diǎn)都配有真實(shí)可運(yùn)行的代碼示例。

二、響應(yīng)式系統(tǒng):核心差異

2.1 React 的響應(yīng)式模型

React 使用不可變數(shù)據(jù)驅(qū)動(dòng)視圖更新。當(dāng) state 變化時(shí),React 會(huì)觸發(fā)重新渲染整棵組件樹(通過 Virtual DOM diff 優(yōu)化)。核心代碼如下:

// React 組件:狀態(tài)驅(qū)動(dòng)
import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchUser(userId).then(data => {
      setUser(data);       // 觸發(fā)重新渲染
      setLoading(false);
    });
  }, [userId]);

  // React 的思維:數(shù)據(jù)變 -> 重新渲染 -> 對(duì)比虛擬 DOM -> 最小化更新
  return loading ? <Spinner /> : <div>{user.name}</div>;
}

關(guān)鍵點(diǎn):React 開發(fā)者習(xí)慣"數(shù)據(jù)在前,視圖在后"——先有 state,再推導(dǎo) UI。狀態(tài)變化后 React 會(huì)自動(dòng)對(duì)比新舊 Virtual DOM,決定哪些真實(shí) DOM 需要更新。

2.2 Vue3 的響應(yīng)式模型

Vue3 使用Proxy 代理直接追蹤數(shù)據(jù)變化,數(shù)據(jù)在哪被用到,Vue3 就知道要更新哪里,不需要手動(dòng)觸發(fā)。

// Vue3 組件:聲明式模板 + 響應(yīng)式數(shù)據(jù)
import { ref, computed, onMounted } from 'vue';
defineComponent({
  setup() {
    // ref 包裝響應(yīng)式數(shù)據(jù)
    const user = ref(null);
    const loading = ref(true);
    const userId = ref(1);
    // 計(jì)算屬性
    const displayName = computed(() => user.value?.name ?? '加載中');
    onMounted(async () => {
      const data = await fetchUser(userId.value);
      user.value = data;   // 直接賦值,Vue3 自動(dòng)追蹤
      loading.value = false;
    });
    return { user, loading, displayName };
  }
});
<!-- Vue3 模板:直接使用響應(yīng)式數(shù)據(jù) -->
<template>
  <div>{{ loading ? '加載中' : displayName }}</div>
</template>

2.3 兩者的核心差異對(duì)比

維度ReactVue3
響應(yīng)式實(shí)現(xiàn)不可變 state + Virtual DOM diffProxy 直接代理 + 依賴追蹤
更新觸發(fā)手動(dòng) setState / useState賦值即更新
渲染粒度組件級(jí),需要 React.memo 優(yōu)化精確到響應(yīng)式依賴的 DOM 節(jié)點(diǎn)
學(xué)習(xí)曲線思維簡(jiǎn)單,但性能優(yōu)化要主動(dòng)上手容易,性能優(yōu)化由框架兜底

三、組件寫法對(duì)照

3.1 Props 傳遞與類型檢查

// React Props 定義
interface UserCardProps {
  name: string;
  age: number;
  avatar?: string;
  onUpdate: (id: number, name: string) => void;
}

function UserCard({ name, age, avatar, onUpdate }: UserCardProps) {
  return <div onClick={() => onUpdate(1, name)}>{name}, {age}</div>;
}
// Vue3 Props 定義(defineProps 配合 TS)
interface UserCardProps {
  name: string;
  age: number;
  avatar?: string;
  emit: (event: 'update', id: number, name: string) => void;
}

const props = defineProps<UserCardProps>();
const emit = defineEmits<{
  update: [id: number, name: string];
}>();

// Vue3 使用 emit
const handleClick = () => emit('update', 1, props.name);

3.2 生命周期對(duì)比

// React useEffect 替代所有生命周期
useEffect(() => {
  // mounted
  console.log('組件掛載');

  return () => {
    // unmounted cleanup
    console.log('組件卸載清理');
  };
}, []); // 空依賴 = didMount + willUnmount

useEffect(() => {
  // didUpdate — 當(dāng) userId 變化時(shí)執(zhí)行
  fetchUser(userId);
}, [userId]);
// Vue3 組合式 API 生命周期鉤子
import { onMounted, onUnmounted, watch } from 'vue';

onMounted(() => {
  console.log('setup 執(zhí)行 = React 的 constructor');
});

watch(userId, (newId) => {
  fetchUser(newId); // 等價(jià)于 React 的 useEffect(() => {...}, [userId])
});

onUnmounted(() => {
  console.log('組件卸載 = React 的 componentWillUnmount');
});

四、Hooks vs Composition API:逐個(gè)對(duì)照

這是兩者最大的差異所在,也是 React 開發(fā)者遷移 Vue3 時(shí)最需要調(diào)整思維的地方。

4.1 useState → ref / reactive

// React
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: '', age: 0 });
setCount(count + 1);
setUser({ ...user, name: 'new name' });
// Vue3
const count = ref(0);           // 基礎(chǔ)類型用 ref
const user = reactive({ name: '', age: 0 }); // 對(duì)象/數(shù)組用 reactive
count.value++;                 // ref 要 .value
user.name = 'new name';         // reactive 直接改

4.2 useEffect → watch / watchEffect

// React:副作用在 useEffect 里
useEffect(() => {
  document.title = `${user.name} 的主頁`;
}, [user.name]);
// Vue3:watch 精確監(jiān)聽
watch(() => user.name, (newName) => {
  document.title = `${newName} 的主頁`;
});

// watchEffect 自動(dòng)收集依賴(類似 useEffect,但更直接)
watchEffect(() => {
  document.title = `${user.name} 的主頁`;
});

4.3 useMemo / useCallback → computed / readonly

// React
const sortedList = useMemo(() =>
  list.filter(x => x.active).sort((a, b) => a.name.localeCompare(b.name)),
  [list]
);
const handleSubmit = useCallback((data) => submit(data), [submit]);
// Vue3
const sortedList = computed(() =>
  list.filter(x => x.active).sort((a, b) => a.name.localeCompare(b.name))
);
const handleSubmit = (data: FormData) => submit(data); // Vue3 不需要 useCallback

4.4 自定義 Hooks → Composables

// React 自定義 Hook
function useUserSearch(keyword) {
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    search(keyword).then(data => {
      setResults(data);
      setLoading(false);
    });
  }, [keyword]);

  return { results, loading };
}
// Vue3 Composables(自定義組合式函數(shù))
function useUserSearch(keyword: Ref<string>) {
  const results = ref([]);
  const loading = ref(false);

  watch(keyword, async (kw) => {
    if (!kw) { results.value = []; return; }
    loading.value = true;
    results.value = await search(kw);
    loading.value = false;
  }, { immediate: true });

  return { results: readonly(results), loading: readonly(loading) };
}

五、常見思維誤區(qū)

誤區(qū)一:用 React 的不可變思維操作 Vue3 響應(yīng)式數(shù)據(jù)

React 開發(fā)者習(xí)慣了 setState({ ...state, key: newVal })(展開合并),在 Vue3 中對(duì) reactive 對(duì)象這樣做會(huì)丟失響應(yīng)式

// 錯(cuò)誤 ? — 展開后變成普通對(duì)象,失去響應(yīng)式
user.value = { ...user.value, name: 'new name' };

// 正確 ? — 直接修改屬性
user.value.name = 'new name';

// 或者用 Object.assign(對(duì) ref)
Object.assign(user.value, { name: 'new name' });

誤區(qū)二:把 useEffect 的依賴當(dāng)成 watchEffect 的寫法

useEffect 依賴數(shù)組是"被動(dòng)觸發(fā)",watchEffect 自動(dòng)收集依賴但會(huì)立即執(zhí)行一次($ 有 lazy: true 選項(xiàng)關(guān)閉)。$ 中不要在 watchEffect 里直接修改被監(jiān)聽的對(duì)象,否則會(huì)導(dǎo)致死循環(huán)。

誤區(qū)三:忘了 .value

ref 包裝的變量在 script 中是引用,必須用 .value 讀寫,但在 <template> 中不需要——Vue3 自動(dòng)解包。

六、狀態(tài)管理方案對(duì)比

場(chǎng)景React 推薦方案Vue3 推薦方案
組件本地狀態(tài)useStateref / reactive
跨組件共享Context + useReducer / Zustandprovide/inject + Pinia
服務(wù)端數(shù)據(jù)React Query / SWRPinia + REST / GraphQL
全局配置ContextPinia store

Pinia vs Redux

// React Redux 風(fēng)格
const userSlice = createSlice({
  name: 'user',
  initialState: { name: '', token: '' },
  reducers: {
    setUser: (state, action) => { state.name = action.payload.name; }
  }
});
// Vue3 Pinia — 更直觀,不需要 action/reducer 分離
export const useUserStore = defineStore('user', {
  state: () => ({ name: '', token: '' }),
  actions: {
    setUser(data) {
      this.name = data.name;
      this.token = data.token;
    },
    async fetchUser(id) {
      const data = await api.getUser(id);
      this.setUser(data);
    }
  }
});

七、總結(jié):遷移 checklist

檢查項(xiàng)React 思維Vue3 正確姿勢(shì)
狀態(tài)更新setState(obj)ref.value = xxx 或 reactiveObj.key = xxx
對(duì)象更新{...obj, key: val}直接賦值或 Object.assign
副作用useEffect(() => {...}, [dep])watch(() => dep, fn) 或 watchEffect(fn)
計(jì)算屬性useMemo(fn, [dep])computed(fn)
組件傳值props + callbacksprops + defineEmits
全局狀態(tài)Context / Redux / ZustandPinia
清理邏輯return () => {...}onUnmounted(() => {...})

到此這篇關(guān)于React轉(zhuǎn)Vue3的避坑指南的文章就介紹到這了,更多相關(guān)React轉(zhuǎn)Vue3避坑內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于react中的常見錯(cuò)誤及解決

    關(guān)于react中的常見錯(cuò)誤及解決

    這篇文章主要介紹了關(guān)于react中的常見錯(cuò)誤及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境

    詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境

    這篇文章主要介紹了詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • 一文帶你搞懂useCallback的使用方法

    一文帶你搞懂useCallback的使用方法

    useCallback是用來幫忙緩存函數(shù)的,當(dāng)依賴項(xiàng)沒有發(fā)生變化時(shí),返回緩存的指針,而props涉及到復(fù)雜對(duì)象類型都是通過指針來傳遞到,下面這篇文章主要給大家介紹了關(guān)于useCallback使用的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • React報(bào)錯(cuò)Element type is invalid解決案例

    React報(bào)錯(cuò)Element type is invalid解決案例

    這篇文章主要為大家介紹了React報(bào)錯(cuò)Element type is invalid解決案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React項(xiàng)目配置axios和反向代理和process.env環(huán)境配置等問題

    React項(xiàng)目配置axios和反向代理和process.env環(huán)境配置等問題

    這篇文章主要介紹了React項(xiàng)目配置axios和反向代理和process.env環(huán)境配置等問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)

    react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)

    react不同于vue,通過在路由里設(shè)置meta元字符實(shí)現(xiàn)路由攔截。本文就詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • React?中使用?Redux?Toolkit?狀態(tài)管理的實(shí)踐

    React?中使用?Redux?Toolkit?狀態(tài)管理的實(shí)踐

    本文主要介紹了Redux的核心概念及Redux?Toolkit的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • React中異步數(shù)據(jù)更新不及時(shí)問題及解決

    React中異步數(shù)據(jù)更新不及時(shí)問題及解決

    這篇文章主要介紹了React中異步數(shù)據(jù)更新不及時(shí)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React+Spring實(shí)現(xiàn)跨域問題的完美解決方法

    React+Spring實(shí)現(xiàn)跨域問題的完美解決方法

    這篇文章主要介紹了React+Spring實(shí)現(xiàn)跨域問題的完美解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • react中JSX的注意點(diǎn)詳解

    react中JSX的注意點(diǎn)詳解

    這篇文章主要為大家詳細(xì)介紹了react中JSX的注意點(diǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論

高雄县| 丰宁| 海阳市| 陆川县| 澄江县| 余姚市| 平潭县| 延吉市| 浏阳市| 临泉县| 黔南| 丰台区| 临泉县| 泾川县| 惠东县| 宁化县| 双峰县| 彰武县| 六盘水市| 广元市| 乌拉特后旗| 常德市| 广元市| 山阳县| 东海县| 逊克县| 叙永县| 兰州市| 乐至县| 合水县| 蓬安县| 芦山县| 桂平市| 东宁县| 河曲县| 石景山区| 汽车| 庆城县| 洛隆县| 临高县| 漳州市|