目录
- 相同点
- 不同点
- DOM编写
- 组件作用域内的CSS
- 状态管理
- 优化
- 代码分离
- 开发框架
- npm下载量对比
- 优缺点对比
- 大厂使用案例
vue及react都是用来构建用户界面的JS框架. 它们在很多解决关键问题的点上都是相通的, 不同点只在于细节上的一些差别. 本文主要针对不同点来详细作对比说明.
相同点
两者大部分主要功能是相同的, 如下:
- 虚拟DOM, 快速修改DOM
- 组件化开发
- 响应式组件
- 服务端渲染
- 应用开发全家桶: 路由 + 状态管理 + 打包等
不同点
1. DOM编写
vue采用模板语法,react采用JSX来编写DOM, 模板语法是在HTML中加入一些赋值markup,而JSX语法是将JS代码与DOM标签混合在一起使用. 对于没有接触过两者的前端开发来说,模板语法更容易理解,上手快,且结构简单,编写容易. 具体区别见下面的例子:
a) VUE模板语法
采用HTML + moustache(双大括号赋值) + 指令的模板语法, 易学,简单,上手非常快.(也支持JSX, 但推荐使用模板语法)
指令: 接收表达式,当表达式变化时,响应式的作用在DOM上.
例子:
待办列表
-
{{ index+1 }}. {{ item.content }}
(完成)
{{ item.createTime}}
上面例子中使用到的模板语法解释:
- v-for: 循环指令, 遍历todoList对象
- @click: v-on:click的缩写,绑定点击事件
- :class: v-bind:class的缩写,表示item.status为true时,添加success到li的class
- {{}}: 大括号赋值语句, 可以接收表达式
- v-if: 条件判断,当值为true时,该DOM才显示
b) react JSX语法
例子:
待办列表
{Object.keys(todoList).forEach((k, i) => (
- {this.clickTask(k)}}
className={todoList[k].status?'success':''}>
{i}. {todoList[k].content}
{todoList[k].status && (完成)}
{{ todoList[k].createTime}}
))}
jsx语法将JS逻辑与DOM标签混在一起,学习成本会比较高,对比模板语法来说编写也复杂一些.
2. 组件作用域内的CSS
vue组件作用域的CSS, 还是写在style标签中, 用正常的CSS语法即可. 而react是采用css in js的思想, 用JS的思想来写CSS. 具体区别参考下面的例子:
a) vue的组件作用域内的CSS
例子:
// 渲染出来后如下
div[data-v-20de4a82] {
color: red
}
vue组件作用域的CSS, 只需要在组件内部的style标签中添加scoped属性即可, 渲染出来的css会在组件的对应标签上添加一个"data-"开头的唯一属性, 并作为CSS的选择定位符
b) react的组件作用域内的CSS
例子:
// style对象
const styles = {color: red, fontSize: '14px'}
// JSX
react组件作用域的CSS, 用JS来写时, 需要将css中以中橫线连接的属性换成驼峰的形式, 还是比较麻烦的.
3. 状态管理
vue中的state, 对于非对象类型的数据修改可直接采用赋值的方式修改, 复杂的对象类型的属性添加才需要用vue的set方法来操作. react的state必须使用state.set方法进行操作, 具体区别参考下面的例子:
a) vue操作state
例子:
// state结构如下
data: {
flag: true,
obj: {
a: 1
}
}
// 修改flag的值
this.flag = false
// 修改obj.a的值
this.obj.a = 2
// 向obj中添加一个新的属性b
this.$set(this.obj, b, 'b1')
可以看出vue操作大部分的state都是非常简单的
b) react操作state
例子:
// state结构如下
state = {
flag: true,
obj: {
a: 1
}
}
// 修改flag
this.setState({flag: false})
// 修改obj.a的值
this.setState({obj: {a: 2}})
// 向obj中添加一个新的属性b
let obj = this.state.obj;
obj.b = 'b1';
this.setState({obj})
react中操作state都需要使用setState方法
4. 优化
react中, 只要state变化, 组件及子组件都会走render方法去看是否需要更新DOM, 当你需要考虑怎么来优化这个点时, 而vue却不存在这样的问题
react的优化方式是当组件的state不常变化时,可以考虑使用pureComponenet. 或者自己在shouldComponentUpdate生命周期的方法中判断该组件的props有没有变化, 当shouldComponentUpdate方法返回false时, 将直接返回跳过后续的生命周期方法. 使用这个方法的前提是, 子组件DOM的变化全部由props决定.
vue框架内部已经对此做了优化, 开发者不需要考虑该类问题, 只需要关注自己的应用本身就可以了.
5. 代码分离
在单页应用中, 代码分离是指除公共资源外, 页面只加载当前页面自己的JS代码, 也就是按需加载.
vue的代码分离很简单, 只需要在路由的component中改用函数返回import()方法导入的异步组件. 而react相对就比较繁琐, 需要借助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. 开发框架
vue官方提供的vue-cli非常强大, 使用vue-cli 能非常方便的创建一个vue的开发框架, 创建的框架内部对webpack已经做了优化配制. 若你需要改变webpack的配制也非常方便, 只需要在vue.config.js中按要求添加你的配制就可以了. 这种方式非常适合初学者, 不需要去关注webpack繁琐的配制项.
react官方也有提供react-create-cli来创建一个开发框架, 但功能只限于此, 想要根据自己的项目需求来搭建框架你还是得去学习webpack的复杂配制.
npm下载量对比
以下是从npm官网弄下来的最近一年的周下载量, 每一个点是当前日期往后一个星期的下载量. 可以看出两个框架的使用量都在增加, vue现在每周的下载量是一年前的3倍左右, react是一年前的2倍左右. vue使用量增长还是比较快的.
优缺点对比
综合上面不同点的分析, 总结出优缺点如下:
1. vue相比于react优点如下:
vue | react | |
---|---|---|
html | 模板语法,上手快 | JSX语法, 学习成本高 |
组件作用域内的CSS | 直接style标签添加scoped属性, css还是原生的css语法 | css in js, js思想来写css, 有转换成本 |
状态管理 | 简单属性直接赋值操作 | 必须调用setState方法来操作state |
渲染优化 | vue不需要考虑 | 采用pureComponent, 还有很多限制及坑 |
代码分离 | 非常简单, 只需要改用import()方法来加载组件 | 需要借用第三方插件,书写也很繁琐 |
开发框架 | vue-cli非常方便的搭建可扩展的开发框架 | 需要去熟悉webpack的各种配制 |
开发习惯 | 更接近原生的前端开发模式: HTML CSS JS | 一切都是JS, 开发模块的方式更接近后端语言 |
学习成本 | 上手快,更接近原生的前端语言 | 复杂度高, 上手慢, 学习成本高 |
2. vue相比于react缺点如下:
- html模板语法不利于调式
- 生态圈, 使用react的人相对较多, react的社区会更大 对应的开源出来的react组件也会比较多
- 原生APP的支持,react有比较成熟的react-native.虽然vue也有Weex, 但还不太完善.
大厂使用案例
使用vue的案例:
网站 | 地址 |
---|---|
饿了么 | https://h5.ele.me/ |
https://www.jianshu.com/ | |
手机搜狐网 | http://m.sohu.com/ |
bilibili直播 | https://live.bilibili.com |
使用react的网站:
网站 | 地址 |
---|---|
www.facebook.com | |
uber | https://www.uber.com/hk/zh-hk/ |
antd | https://ant.design/ |
知乎 | https://www.zhihu.com/signup?next=%2F |