鶴山網(wǎng)站建設(shè)易搜互聯(lián)品牌推廣內(nèi)容
原文:
https://icheng.github.io/2023/08/10/Vue%E8%BD%ACReact%E6%8C%87%E5%8D%97/
JSX
先介紹 React 唯一的一個語法糖:JSX。
理解 JSX 語法并不困難,簡單記住一句話,遇到 {}
符號內(nèi)部解析為 JS 代碼,遇到成對的 <>
符號內(nèi)部解析為 HTML 代碼。
當(dāng)你寫下這個 React 組件時:
import React from 'react';function MyComponent(props) {return <div>{props.hello}</div>
}
最終會被自動工具翻譯成:
import React from 'react';function MyComponent(props) {return React.createElement('div', null, props.hello);
}
React 就是通過這個小小語法糖,實現(xiàn)在 JS 里面寫 HTML,可能有小伙伴會說 HTML 與 JS 分離不是更好嗎?責(zé)職分明,混合只會更亂。但當(dāng)你體驗到代碼自動提示,自動檢查,以及調(diào)試時精確定位到一行代碼的好處時,就清楚 React 和 Vue 的差距了。
文本插值
vue種采用雙括號
<span>Message: {{ msg }}</span>
react采用單括號
function MyComponent(props) {let msg = 'XXX'return <div>{ msg }</div>
}
Attribute 綁定
vue中 想要響應(yīng)式地綁定一個 attribute,應(yīng)該使用 v-bind
指令
<div v-bind:id="dynamicId"></div>
<div :id="dynamicId"></div>
react中,使用單引號,或者使用單括號包裹表示動態(tài)綁定
function App () {let tmpID = '12'return (<div className='App'><div id='12'>id</div><div id={tmpID}>id</div></div>);
}
動態(tài)綁定多值:
function App () {let tmpObject = {id: 13,className: 'wrapper'}return (<div className='App'><div {...tmpObject}>id</div></div>);
}即:<div id="13" class="wrapper">id</div>
參數(shù) Arguments
某些指令會需要一個“參數(shù)”,Vue在指令名后通過一個冒號隔開做標(biāo)識。例如用 v-bind
指令
<a v-bind:href="url"> ... </a><!-- 簡寫 -->
<a :href="url"> ... </a>
React中則沒有指令一說,而是采用如下方式:
// href跳轉(zhuǎn)
function App () {let tmpURL = 'https://www.XXXXXXXX'return (<div className='App'><a href={tmpURL}></a></div>);
}
使用 JS 表達(dá)式
React 遇到 {}
符號內(nèi)部解析為 JS 代碼
function App () {let tmpString = '--';return (<div className='App'><div >{1 + 1}</div><div >{'a' + 'b'}</div><div >{`1${tmpString}1`}</div></div>);
}
即:
<div>2</div>
<div>ab</div>
<div>1--1</div>
事件處理
Vue中綁定事件處理:
<!-- `greet` 是上面定義過的方法名 -->
<button @click="greet">Greet</button>
React可以通過在組件中聲明 事件處理 函數(shù)來響應(yīng)事件
React中點擊事件使用小駝峰形式:onClick
在標(biāo)簽上寫函數(shù):
function App () {return (<div className='App'><div onClick={() => alert('點擊出現(xiàn)彈框')}>按鈕</div></div>);
}
提前聲明函數(shù):
function App () {function myFun () {alert('點擊出現(xiàn)彈框')}return (<div className='App'><div onClick={myFun}>按鈕</div></div>);
}
注意,onClick={handleClick}
的結(jié)尾沒有小括號!不要 調(diào)用 事件處理函數(shù):你只需 傳遞給事件 即可。當(dāng)用戶點擊按鈕時,React 會調(diào)用你的事件處理函數(shù)。
函數(shù)傳參:
function App () {function myFun (str) {alert(str)}return (<div className='App'><div onClick={() => myFun('點擊出現(xiàn)彈框')}>按鈕</div></div>);
}
動態(tài)參數(shù)
Vue在指令參數(shù)上也可以使用一個 JavaScript 表達(dá)式,需要包含在一對方括號內(nèi):
<a v-bind:[attributeName]="url"> ... </a><!-- 簡寫 -->
<a :[attributeName]="url"> ... </a>
舉例來說,如果你的組件實例有一個數(shù)據(jù)屬性 attributeName
,其值為 "href"
,那么這個綁定就等價于 v-bind:href
。
React 也可以通過動態(tài)參數(shù)綁定
function App () {const obj = {onClick: () => alert('點擊出現(xiàn)彈框'),// ...還可以寫更多事件}return (<div className='App'><div {...obj}>按鈕</div></div>);
}
修飾符 Modifiers
vue 修飾符是以點開頭的特殊后綴
表明指令需要以一些特殊的方式被綁定。例如 .prevent
修飾符會告知 v-on
指令對觸發(fā)的事件調(diào)用 event.preventDefault()
:
<form @submit.prevent="onSubmit">...</form>
React 則是依靠于JS基礎(chǔ)
function App () {function onSubmit(e){e.preventDefault();e.stopPropagation();}return (<div className='App'><form onSubmit={onSubmit}><button type='submit'></button></form></div>);
}
響應(yīng)式
為了實現(xiàn)視圖更新,VUE中響應(yīng)式是一個重要的概念
而 React 中并沒有響應(yīng)式這個概念,要實現(xiàn)視圖更新,需要在 React 引入 useState
通常,你會希望你的組件 “記住” 一些信息并展示出來。例如,也許你想計算一個按鈕被點擊的次數(shù)。要做到這一點,你需要在你的組件中添加 state。
首先,從 React 引入 useState
:
import { useState } from 'react';
現(xiàn)在你可以在你的組件中聲明一個 state 變量:
function MyButton() {const [count, setCount] = useState(0);// ...
你將從 useState
中獲得兩樣?xùn)|西:當(dāng)前的 state(count
),以及用于更新它的函數(shù)(setCount
)。你可以給它們起任何名字,但按照慣例,需要像這樣 [something, setSomething]
為它們命名。
第一次顯示按鈕時,count
的值為 0
,因為你把 0
傳給了 useState()
。當(dāng)你想改變 state 時,調(diào)用 setCount()
并將新的值傳遞給它。點擊該按鈕計數(shù)器將遞增:
function MyButton() {const [count, setCount] = useState(0);function handleClick() {setCount(count + 1);}return (<button onClick={handleClick}>Clicked {count} times</button>);
}
React 將再次調(diào)用你的組件函數(shù)。這次,count
會變成 1
。接著,變成 2
。以此類推。
如果你多次渲染同一個組件,每個組件都會擁有自己的 state。你可以嘗試點擊不同的按鈕:
計算屬性
Vue中使用 watch 來實現(xiàn)計算屬性(緩存計算的結(jié)果)
React 在組件的頂層調(diào)用 useMemo
來緩存每次重新渲染都需要計算的結(jié)果
import { useState } from 'react';
import { useMemo } from 'react';function App () {const [user] = useState({ firstname: 'a', lastname: 'b' })const fullname = useMemo(() => {return user.firstname + user.lastname;}, [user.firstname, user.lastname])return (<div className='App'>{fullname}</div>);
}
useMemo(calculateValue, dependencies)
參數(shù)
calculateValue
:要緩存計算值的函數(shù)。它應(yīng)該是一個沒有任何參數(shù)的純函數(shù),并且可以返回任意類型。React 將會在首次渲染時調(diào)用該函數(shù);在之后的渲染中,如果dependencies
沒有發(fā)生變化,React 將直接返回相同值。否則,將會再次調(diào)用calculateValue
并返回最新結(jié)果,然后緩存該結(jié)果以便下次重復(fù)使用。dependencies
:所有在calculateValue
函數(shù)中使用的響應(yīng)式變量組成的數(shù)組。響應(yīng)式變量包括 props、state 和所有你直接在組件中定義的變量和函數(shù)。如果你在代碼檢查工具中 配置了 React,它將會確保每一個響應(yīng)式數(shù)據(jù)都被正確地定義為依賴項。依賴項數(shù)組的長度必須是固定的并且必須寫成[dep1, dep2, dep3]
這種形式。React 使用Object.is
將每個依賴項與其之前的值進行比較。
綁定 HTML class
數(shù)據(jù)綁定的一個常見需求場景是操縱元素的 CSS class 列表和內(nèi)聯(lián)樣式。因為 class
和 style
都是 attribute
Vue中可以給 :class
(v-bind:class
的縮寫) 傳遞一個對象來動態(tài)切換 class:
<div :class="{ active: isActive }"></div>
上面的語法表示 active
是否存在取決于數(shù)據(jù)屬性 isActive
的真假值。
React實現(xiàn)方式基于js語法,其實有多種實現(xiàn)方式,列舉三元運算符方式如下:
function App () {let showColor = falsereturn (// 現(xiàn)有box-show、box-hide兩個class樣式<div className={showColor ? 'box-show' : 'box-hide'}></div>);
}
語法糖轉(zhuǎn)換
習(xí)慣 Vue 的同學(xué)都知道很多語法糖,比如 v-if
、v-for
、v-bind
、v-on
等,相比 Vue,React 只有一個語法糖,那就是 jsx/tsx。v-if
這些功能在 React 上都是通過原生 javascript 實現(xiàn)的,慢慢你會發(fā)現(xiàn),其實你學(xué)的不是 React,而是 Javascipt,React 賦予你通過 js 完整控制組件的能力,這部分明顯比 Vue 的語法糖更加靈活,糖太多容易引來蟲子(Bug)
條件渲染
vue 中寫法是這樣:
<div><h1 v-if="ishow">Vue is awesome!</h1><h1 v-else>else</h1>
</div>
在 React 函數(shù)組件中,只需使用 js 三目運算符語法即可完成條件渲染的功能?;蛘呤褂?&& 邏輯,記住下面一句話就能過理解了:
遇到
{}
符號內(nèi)部解析為 JS 代碼,遇到成對的<>
符號內(nèi)部解析為 HTML 代碼
function App () {const ishow = falsereturn (<div>{ishow ? <div>awesome</div> : <div>else</div>}{ishow && <h1>React!</h1>}</div>);
}
列表渲染
Vue中通過v-for進行列表渲染
React 通過 js 的數(shù)組語法 map,將數(shù)據(jù)對象映射為 DOM 對象。只需學(xué)會 js,無需記住各種指令,如果要做列表過濾,直接使用 items.filter(...).map(...)
鏈?zhǔn)秸{(diào)用即可,語法上更加靈活,如果為了提高渲染性能,使用 useMemo 進行優(yōu)化即可,類似 Vue 的 computed。
function App () {const arr = [{ message: 'react' }, { message: 'JS' }]return (<div>{arr.map((items, index) => <li key={index}>{items.message}</li>)}</div >);
}
偵聽器
Vue中使用 watch監(jiān)聽數(shù)據(jù)變化,觸發(fā)回調(diào)
React中可以使用 useEffect 實現(xiàn)
function App () {const [user, setUser] = useState({firstname: 'a',lastname: 'b'})useEffect(() => {console.log("1111")}, [user.firstname])return (<div><button onClick={() => setUser({ ...user, firstname: 'a2' })}></button></div >);
}