目錄
- 相同點(diǎn)
- 不同點(diǎn)
- DOM編寫
- 組件作用域內(nèi)的CSS
- 狀態(tài)管理
- 優(yōu)化
- 代碼分離
- 開發(fā)框架
- npm下載量對(duì)比
- 優(yōu)缺點(diǎn)對(duì)比
- 大廠使用案例
vue及react都是用來構(gòu)建用戶界面的JS框架. 它們?cè)诤芏嘟鉀Q關(guān)鍵問題的點(diǎn)上都是相通的, 不同點(diǎn)只在于細(xì)節(jié)上的一些差別. 本文主要針對(duì)不同點(diǎn)來詳細(xì)作對(duì)比說明.
相同點(diǎn)
兩者大部分主要功能是相同的, 如下:
- 虛擬DOM, 快速修改DOM
- 組件化開發(fā)
- 響應(yīng)式組件
- 服務(wù)端渲染
- 應(yīng)用開發(fā)全家桶: 路由 + 狀態(tài)管理 + 打包等
不同點(diǎn)
1. DOM編寫
vue采用模板語法,react采用JSX來編寫DOM, 模板語法是在HTML中加入一些賦值markup,而JSX語法是將JS代碼與DOM標(biāo)簽混合在一起使用. 對(duì)于沒有接觸過兩者的前端開發(fā)來說,模板語法更容易理解,上手快,且結(jié)構(gòu)簡單,編寫容易. 具體區(qū)別見下面的例子:
a) VUE模板語法
采用HTML + moustache(雙大括號(hào)賦值) + 指令的模板語法, 易學(xué),簡單,上手非趁岢簦快.(也支持JSX, 但推薦使用模板語法)
指令: 接收表達(dá)式,當(dāng)表達(dá)式變化時(shí),響應(yīng)式的作用在DOM上.
例子:
<div class="todo-list">
<h3>待辦列表</h3>
<ul class="todo-ul">
<li v-for="(item, key, index) in todoList" :key="key"
:id="key" @click="clickTask(key)" :class="{success: item.status}">
{{ index+1 }}. {{ item.content }}
<span v-if="item.status">(完成)</span>
<span class="create-time">{{ item.createTime}}</span>
</li>
</ul>
</div>
上面例子中使用到的模板語法解釋:
- v-for: 循環(huán)指令, 遍歷todoList對(duì)象
- @click: v-on:click的縮寫,綁定點(diǎn)擊事件
- :class: v-bind:class的縮寫,表示item.status為true時(shí),添加success到li的class
- {{}}: 大括號(hào)賦值語句, 可以接收表達(dá)式
- v-if: 條件判斷,當(dāng)值為true時(shí),該DOM才顯示
b) react JSX語法
例子:
<div className="todo-list">
<h3>待辦列表</h3>
<ul class="todo-ul">
{Object.keys(todoList).forEach((k, i) => (
<li key={i} id={k} onClick={() => {this.clickTask(k)}}
className={todoList[k].status?'success':''}>
{i}. {todoList[k].content}
{todoList[k].status && <span>(完成)</span>}
<span class="create-time">{{ todoList[k].createTime}}</span>
</li>
))}
</ul>
</div>
jsx語法將JS邏輯與DOM標(biāo)簽混在一起,學(xué)習(xí)成本會(huì)比較高,對(duì)比模板語法來說編寫也復(fù)雜一些.
2. 組件作用域內(nèi)的CSS
vue組件作用域的CSS, 還是寫在style標(biāo)簽中, 用正常的CSS語法即可. 而react是采用css in js的思想, 用JS的思想來寫CSS. 具體區(qū)別參考下面的例子:
a) vue的組件作用域內(nèi)的CSS
例子:
<style scoped>
div {
color: red;
}
</style>
// 渲染出來后如下
div[data-v-20de4a82] {
color: red
}
vue組件作用域的CSS, 只需要在組件內(nèi)部的style標(biāo)簽中添加scoped屬性即可, 渲染出來的css會(huì)在組件的對(duì)應(yīng)標(biāo)簽上添加一個(gè)"data-"開頭的唯一屬性, 并作為CSS的選擇定位符
b) react的組件作用域內(nèi)的CSS
例子:
// style對(duì)象
const styles = {color: red, fontSize: '14px'}
// JSX
<div style={styles}></div>
react組件作用域的CSS, 用JS來寫時(shí), 需要將css中以中橫線連接的屬性換成駝峰的形式, 還是比較麻煩的.
3. 狀態(tài)管理
vue中的state, 對(duì)于非對(duì)象類型的數(shù)據(jù)修改可直接采用賦值的方式修改, 復(fù)雜的對(duì)象類型的屬性添加才需要用vue的set方法來操作. react的state必須使用state.set方法進(jìn)行操作, 具體區(qū)別參考下面的例子:
a) vue操作state
例子:
// state結(jié)構(gòu)如下
data: {
flag: true,
obj: {
a: 1
}
}
// 修改flag的值
this.flag = false
// 修改obj.a的值
this.obj.a = 2
// 向obj中添加一個(gè)新的屬性b
this.$set(this.obj, b, 'b1')
可以看出vue操作大部分的state都是非常簡單的
b) react操作state
例子:
// state結(jié)構(gòu)如下
state = {
flag: true,
obj: {
a: 1
}
}
// 修改flag
this.setState({flag: false})
// 修改obj.a的值
this.setState({obj: {a: 2}})
// 向obj中添加一個(gè)新的屬性b
let obj = this.state.obj;
obj.b = 'b1';
this.setState({obj})
react中操作state都需要使用setState方法
4. 優(yōu)化
react中, 只要state變化, 組件及子組件都會(huì)走render方法去看是否需要更新DOM, 當(dāng)你需要考慮怎么來優(yōu)化這個(gè)點(diǎn)時(shí), 而vue卻不存在這樣的問題
react的優(yōu)化方式是當(dāng)組件的state不常變化時(shí),可以考慮使用pureComponenet. 或者自己在shouldComponentUpdate生命周期的方法中判斷該組件的props有沒有變化, 當(dāng)shouldComponentUpdate方法返回false時(shí), 將直接返回跳過后續(xù)的生命周期方法. 使用這個(gè)方法的前提是, 子組件DOM的變化全部由props決定.
vue框架內(nèi)部已經(jīng)對(duì)此做了優(yōu)化, 開發(fā)者不需要考慮該類問題, 只需要關(guān)注自己的應(yīng)用本身就可以了.
5. 代碼分離
在單頁應(yīng)用中, 代碼分離是指除公共資源外, 頁面只加載當(dāng)前頁面自己的JS代碼, 也就是按需加載.
vue的代碼分離很簡單, 只需要在路由的component中改用函數(shù)返回import()方法導(dǎo)入的異步組件. 而react相對(duì)就比較繁瑣, 需要借助react-loadable. 具體差別見下面的例子:
a) vue的代碼分離
步驟:
1. 安裝babel插件: npm install @babel/plugin-syntax-dynamic-import --save-dev
2. 在.babelrc中添加該插件
3. vue-router路由中, component加載改用import()方法:
{ path: '/todo', component: () => import('./module/todo/Index.vue') }
b) react的代碼分離
步驟:
1. 安裝babel插件: npm install @babel/plugin-syntax-dynamic-import --save-dev
2. 在.babelrc中添加該插件
3. 組件加載需要借用react-loadable插件: npm install react-loadable --save-dev:
{
path: '/todo',
component: Loadable({
loader: () => import('./module/todo/Index.vue'),
loading: (props) => null
})
}
6. 開發(fā)框架
vue官方提供的vue-cli非常強(qiáng)大, 使用vue-cli 能非常方便的創(chuàng)建一個(gè)vue的開發(fā)框架, 創(chuàng)建的框架內(nèi)部對(duì)webpack已經(jīng)做了優(yōu)化配制. 若你需要改變webpack的配制也非常方便, 只需要在vue.config.js中按要求添加你的配制就可以了. 這種方式非常適合初學(xué)者, 不需要去關(guān)注webpack繁瑣的配制項(xiàng).
react官方也有提供react-create-cli來創(chuàng)建一個(gè)開發(fā)框架, 但功能只限于此, 想要根據(jù)自己的項(xiàng)目需求來搭建框架你還是得去學(xué)習(xí)webpack的復(fù)雜配制.
npm下載量對(duì)比
以下是從npm官網(wǎng)弄下來的最近一年的周下載量, 每一個(gè)點(diǎn)是當(dāng)前日期往后一個(gè)星期的下載量. 可以看出兩個(gè)框架的使用量都在增加, vue現(xiàn)在每周的下載量是一年前的3倍左右, react是一年前的2倍左右. vue使用量增長還是比較快的.
優(yōu)缺點(diǎn)對(duì)比
綜合上面不同點(diǎn)的分析, 總結(jié)出優(yōu)缺點(diǎn)如下:
1. vue相比于react優(yōu)點(diǎn)如下:
vue | react | |
---|---|---|
html | 模板語法,上手快 | JSX語法, 學(xué)習(xí)成本高 |
組件作用域內(nèi)的CSS | 直接style標(biāo)簽添加scoped屬性, css還是原生的css語法 | css in js, js思想來寫css, 有轉(zhuǎn)換成本 |
狀態(tài)管理 | 簡單屬性直接賦值操作 | 必須調(diào)用setState方法來操作state |
渲染優(yōu)化 | vue不需要考慮 | 采用pureComponent, 還有很多限制及坑 |
代碼分離 | 非常簡單, 只需要改用import()方法來加載組件 | 需要借用第三方插件,書寫也很繁瑣 |
開發(fā)框架 | vue-cli非常方便的搭建可擴(kuò)展的開發(fā)框架 | 需要去熟悉webpack的各種配制 |
開發(fā)習(xí)慣 | 更接近原生的前端開發(fā)模式: HTML CSS JS | 一切都是JS, 開發(fā)模塊的方式更接近后端語言 |
學(xué)習(xí)成本 | 上手快,更接近原生的前端語言 | 復(fù)雜度高, 上手慢, 學(xué)習(xí)成本高 |
2. vue相比于react缺點(diǎn)如下:
- html模板語法不利于調(diào)式
- 生態(tài)圈, 使用react的人相對(duì)較多, react的社區(qū)會(huì)更大 對(duì)應(yīng)的開源出來的react組件也會(huì)比較多
- 原生APP的支持,react有比較成熟的react-native.雖然vue也有Weex, 但還不太完善.
大廠使用案例
使用vue的案例:
網(wǎng)站 | 地址 |
---|---|
餓了么 | https://h5.ele.me/ |
簡書 | http://www.reibang.com/ |
手機(jī)搜狐網(wǎng) | http://m.sohu.com/ |
bilibili直播 | https://live.bilibili.com |
使用react的網(wǎng)站:
網(wǎng)站 | 地址 |
---|---|
www.facebook.com | |
uber | https://www.uber.com/hk/zh-hk/ |
antd | https://ant.design/ |
知乎 | https://www.zhihu.com/signup?next=%2F |