框架對比
/ | Vue | React |
---|---|---|
單文件直接引入 | vue.js | react.js + react-dom.js + babel.js |
構建項目 | vue-cli | create-react-app |
虛擬DOM | √ | √ |
虛擬DOM區域(掛載區域) | el 參數值 | ReactDOM.render() 第二個參數值 |
數據驅動 | √ | √ |
Model數據源 | 初始化,定義在data:{} 或 data () { return {} }裏 | 在state裏 constructor () { this.state = {} } |
數據渲染 | {{ }} 插值渲染 支持表達式 | JSX { } 表達式 |
列表渲染 | v-for | 在JSX 內構建一個元素集合 {this.state.arr.map((item,index)=><li key={index}>{item}</li>)} |
條件渲染 | v-if | {this.state.show? <h1>條件渲染</h1> : null} |
子組件內元素渲染 | slot | this.props.children |
動態綁定 | v-bind | title={this.state.title} |
數據更新 | 重新賦值 this.id = xxx; / this.$set() | this.setState({id:xx}) 更新數據 |
指令 | 有 | 無 |
計算屬性 | 有 | 無 |
添加class | class / :class | 使用className className=“red” |
動態切換class | :class="[show? ‘class1’: ‘class2’]" | className={this.state.show ? “class1” : “class2”} |
style行間 | style / :style | jsx寫法 style={{color:“pink”}} |
css作用域(私有) | style scoped | CSS Modules |
ref | √ | √ |
事件寫法 | @click=“clickFn” | onClick={this.clickFn.bind(this)} |
事件處理函數 | methods: {}裏 | 與render(){} 方法同級 |
生命週期鉤子函數 | created() mounted() 等 | componentDidMount() componentDidUpdate() 等 |
創建組件 | Vue.component全局 / components:{} 局部 | function組件 / class組件 正好對應 Redux中的UI組件和容器組件,一個負責內容展示,一個負責操作數據 |
組件定義規則 | 1.kebab-case (短橫線分隔命名) 2.PascalCase (大駝峯式) | 爲了區分原生標籤,組件必須大寫 |
組件特點 | .vue文件 分html、js、css三塊 | all in js |
組件自身作用域 | 有 data裏的數據屬於組件本身 | 有 state數據屬於自身類 |
過渡動畫 | transition組件 | 使用react-transition-group |
數據流向 | 單向數據流 | 單向數據流 |
數據雙向綁定 | v-model | 受控組件(onChange & value ) |
屬性監聽 | watch | static getDerivedStateFromProps(props, state) 拿到即將更新後的props和state。只能自己去手動對比 |
監聽DOM變化 | nextTick() | 無,只能從componentDidUpdate()取DOM,類似Vue 的updated()生命週期 |
父組件向子組件傳值 | 同爲單向數據流,props往下傳值 - 需要在子組件接收props:[‘xx’],然後就可以使用xx值 | 同爲單向數據流,props往下傳值 - 直接使用this.props.xx 取到值 |
props數據類型限定 | 在props對象中限定具體類型 | PropTypes 需單獨引包 |
組件跨級傳值 | context | 無 |
子組件向父組件傳值 | 均使用回調函數通知父組件。子組件this.$emit觸發父組件事件,父級在監聽事件中獲取子組件傳遞的值 | 均使用回調函數通知父組件。子組件this.props.xx 觸發父組件事件,父級在監聽事件中獲取子組件傳遞的值 |
路由對比
/ | vue-router | react-router |
---|---|---|
路由 | vue-router | react-router |
狀態管理對比
/ | Vuex | React-Redux |
---|---|---|
狀態 | state | state |
狀態倉庫 | Store | Store |
狀態的計算屬性 | 有 state的計算屬性,getters(其實就是基於Vue的計算屬性) | 無 |
Store單一數據源 | √ | √ |
定義Store | new Vuex.Store() | createStore(reducers) 需要reducers純函數 |
組件如何拿到state | new Vue() 把store注入到store選項上,成爲this實例的屬性,讓各個組件都可以拿到 | 給根組件套上標籤,在頂層傳入store, 子孫組件通過context拿到state,但是UI組件必須使用connect()方法進行裝飾,在使用mapStateToProps映射後,取值 |
各自框架中獲取state | $store.state.xx (template) this.$store.state.xx (js) |
this.props.xx |
修改狀態方法 | The only way to actually change state in a Vuex store is by committing a mutation. 提交 mutation | The only way to change the state tree is to emit an action, an object describing what happened. 觸發action,一個描述發生什麼的對象 |
修改狀態(同步) | view——>commit——>mutations——>state變化——>view變化(同步) | view——>actions——>reducer——>state變化——>view變化(同步) |
修改狀態(異步) | view——>dispatch——>actions——>mutations——>state變化——>view變化(異步) | view——>actions——>redux middleware——>actions——>reducer——>state變化——>view變化 (異步) |
同步/異步處理方式 | 提出mutations同步,actions異步,兩者相不干擾 | 同步dispatch進入reducer改狀態,異步需要配置中間件,在進入dispatch()後,在中間件層做處理。 Dva借鑑了Vuex |
原store更改狀態寫法 | store.commit() / store.dispatch() | store.dispatch() |
各自框架中的修改狀態 | 因store掛載到實例下,所以可以直接使用實例的對象方法。 this.$store.commit() / this.$store.dispatch() |
mapDispatchToProps映射Action後,調用一個action creator函數 this.props.Fn(),去執行dispatch操作 |
更新狀態 | mutations 直接更新狀態。 非純函數 | reducer返回新狀態,並不是去更新值。 純函數 |
狀態變化如何更新View層 | Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新。 | 組件訂閱mapStateToProps,當映射state的部分值改變時會執行this.setState(),重新渲染View |
模塊化 | 有 多個module,類似一個小store,每個小module有自己的state,actions等 | 無 Dva有namespace |
基於各自框架
/ | Vue | React |
---|---|---|
UI庫 | element-ui iview 等 | Ant-design 等 |
多端統一開發框架 | uni-app | Taro |