Vue 與 React 常見對照

將專案從vue轉成react時順便紀錄:

狀態與資料

Vue 3React差異重點
ref() / reactive()useStateReact 不能直接改值,必須呼叫 setXxx,物件要複製出新的
computed()useMemoVue 自動追蹤依賴;React 要自己寫依賴陣列
watch(x, fn)useEffect(fn, [x])依賴變了就執行
onMounteduseEffect(fn, [])依賴陣列為空 = 只在掛載時執行一次
onUnmounteduseEffect 回傳的清理函式return () => clearInterval(timer)(Dashboard.tsx)
ref="el" 取 DOMuseRef也用來存「不影響畫面」的值

元件之間傳資料

Vue 3React本專案例子
props函式參數 { width }LocaleSelect({ width })
emit('事件’)把函式當 props 傳下去,子元件呼叫它Select 的 onChange
provide / injectContext(createContext + useContext)SystemDataContext、ScanContext、PageMetaContext
<slot>childrenScanProvider({ children })
v-modelvalue + onChange 兩個一起寫<Input value={wordKey} onChange={…} />

模板語法

VueReact (JSX)
v-if="x"{x && <div/>} 或 {x ? <A/> : <B/>}
v-for="i in list" :key="i.id"{list.map(i => <li key={i.id}/>)}
{{ text }}{text}
:class="{ active: x }"className={x ? 'active’ : "}
class="…"className="…"(class 是 JS 保留字)
@click="fn"onClick={fn}
:disabled="x"disabled={x}
v-showstyle={{ display: x ? 'block’ : 'none’ }}
$t('key’)const { t } = useTranslation() 再 t('key’)

路由

Vue RouterReact Router
<router-view><Outlet />(MainLayout.tsx)
router.push('/x’)navigate('/x’),const navigate = useNavigate()
router.back()navigate(-1)
this.$route.query.reqnoconst [params] = useSearchParams() 再 params.get('reqno’)
router.beforeEach路由守衛元件(RequireAuth)

三個最容易踩雷的差異

1. 更新是「重新執行整個函式」,不是「追蹤變動」

Vue 的 setup() 只跑一次;React 的元件函式每次更新都會從頭跑。元件裡的普通變數在每次渲染都會重新建立,要保留的值必須放 useState 或 useRef。

2. useEffect 的依賴陣列是你的責任

useEffect(() => { load() }, [range, dept])   // range 或 dept 變了才重新執行

漏寫會拿到舊值,多寫會執行太頻繁。專案裡有幾處加了 // eslint-disable-next-line react-hooks/exhaustive-deps,是刻意不列入某些依賴,旁邊有寫原因。

3. 開發模式 useEffect 會跑兩次

這是 StrictMode 的行為,正式版不會。所以 effect 裡要能「清理乾淨」,例如計時器要 clearInterval。

對照速記

  • Vue 是「響應式」:你改資料,框架知道誰依賴它。
  • React 是「重新計算」:你通知它資料變了,它重新執行元件,再比對差異更新畫面。

關於站主

Shiro

因為興趣無限擴張,一直很猶豫要不要寫一個很雜的Blog,後來還是這麼做了。

聯絡:shiro050102✦gmail.com  ✦請自行更換成@