上次更新博客是在5/24了。公司的工作也比較多所以就沒有更新。
今天看了一篇文章,講的是React和Vue的區別。所以今天主要講下這個。
文章傳送門:React和Vue的書寫特性差異
渲染過程
React
React的生命週期有以下幾個方法:
1. componentWillMount: 這個方法會在組件的第一次渲染前調用。一個組件渲染只會調用一次該方法,除非重新生成組件。
2. componentDidMount: 這個方法同componentWillMount會在第一次渲染後調用,也是一次生成只調用一次。
3. componentWillReceiveProps(nextProps): 組件在接收到新的props會調用,其參數nextProps表示改變後的props,可用this.props訪問改變前的props。
4. shouldComponentUpdate(nextProps, nextState): React會根據State和Props的變化判斷組件是否需要重新渲染,若返回true則表示重新渲染。
5. componentWillUpdate: 在組件將要更新前的時候調用,此時還沒有觸發render()
6. componentDidUpdate: 在組件更新後調用。
7. componentWillUnmount: 在組件被移除前被調用。
這幾個方法在使用react的時候很常用,因此清楚瞭解它們的調用順序和原因很重要。
下面這張圖片描述得很清楚:
可以看到,當props改變的時候,首先會調用componentWillReceiveProps。但是則state的改變是直接調用shouldComponentUpdate。
還有,重新渲染 不等於 重新生成。 圖片中看到,render後會直接回到運行中的狀態而非componentWillMount。
shouldComponentUpdate用於告訴組件是否應該重新渲染,因此我們可以在該方法中判斷是否應該重新渲染。
這裏要注意的是,shouldComoponentUpdate不能讓他永遠返回true,否則會導致每一次的無關緊要的改動都會重新渲染,這樣的性能會下降。
比如使用React的PureComponent時,react對state的改變的比較是淺比較的,比如
this.state = {
data: {
lh: {
name: 'lihui',
age: 18,
}
}
}
此時你使用this.setState({ data.lh.name: 'csy' });
,其實你改變了state但你會發現組件並沒有重新渲染。
這就是淺比較的原因,淺比較會簡單比較值而非具體的改變。此時你改變的只是lh
中的一個屬性值name
,lh
的引用依舊沒變,因此會被認爲state沒有改變。
解決的方法是使用immutable
對象,每次改動時會返回一個新的對象,這個對象就是新的引用,所以改變會被探測到。這裏具體的方法就省略了。
Attention: 在ComponentWillMount
或者ComponentWillReceiveProps
中調用setState
是無法立即得到新的state的,這是因爲這兩個方法會在執行後再對state進行合併。
shouldUpdateConponent
和ComponentWillUpdate
是不可以在裏面調用setState的,否則會循環調用導致崩潰。
Vue
相較於React,Vue的生命週期則更好理解了。
Vue沒有什麼接受新改變的props和state,而是監聽data的改變,data改變後觸發beforeUpdate函數並重新渲染。
其實我對vue的瞭解還不算太深入,希望有人可以解答下這個部分。
入口
React
React.render(
<App />,
document.getElementById('app')
);
<App />
表示一個組件,上面語句表示的是將該組件在app這個元素內進行渲染。
Vue
const app = new Vue({
render: (h) => h(App) // App爲根組件
}).$mount('#app')
同一種結果,React和Vue在入口方面的不同。
組件定義
React定義組件
// 組件定義
export default Component extends React.Component{
// ...
}
// 引入組件
import Component from './component';
export default About extends React.Component{
render() {
return (
<div>
<Component></Component>
</div>
);
}
}
Vue
// 組件定義
<template>
div
p
</template>
<script>
export default {
// ...
}
</script>
// 引入組件
<template>
div
my-component
</template>
<script>
import myComponent from './myComponent';
export default {
components: {
myComponent,
}
}
</script>
組件狀態修改
組件狀態在React中是state,在Vue中是data
React
React修改state需要通過this.setState({ test: 1 });
Vue
Vue修改data只需要this.age = 18;
即可。
JSX / template
React用的是JSX語法,而Vue用的是Template語法。
條件渲染和列表渲染
React
條件渲染
// ...
render() {
return (
<div>
{
this.getChild();
}
</div>
)
}
getChild = () => {
switch(condition) {
case 'xx':
return (
<div></div>
)
}
}
列表渲染
// ...
render() {
return (
<div>
{
this.state.actions.map((action) => {
return (
<p>{action.name}</p>
)
})
}
</div>
)
}
Vue
條件渲染
<div v-if="this.isShow"></div>
<div v-else></div>
列表渲染
<div v-for="item in this.notes">
<p>
{{item.name}}
</p>
</div>
雙向數據綁定
React
這個地方我真的有感觸頗深,比如當前需要渲染一個input元素。如下
<input defalutValue='default'></input>
此時可能改變了一個state要對input進行重新渲染,前提是你之前在這個input裏有輸入。
你會發現重新渲染後的input還是保留着你剛剛的值。
這個怎麼解決?
這就是因爲React中沒有實現雙向數據綁定的問題了。如何自己實現呢?
<input defalutValue='default' value={this.state.someVlaue}></input>
使用value={this.state.someValue}
使value的值綁定在someValue之上。
但是綁定了之後你會發現,沒有辦法輸入了?!
因此此時需要我們定義一個onChange事件,這個事件會傳入一個e對象,使用這個對象的e.target.value
將用戶輸入的值再保存到someValue上。
<input defalutValue='default' value={this.state.someVlaue} onChange={(e) => this.onInputChange(e)}></input>
onInputChange = (e) => {
this.setState({ someValue: e.target.value });
}
Vue
沒有對比就沒有傷害,Vue中的雙向數據綁定簡單多了。如下
<input v-model="someValue"></input>
待更~