react和vue能力对比
# 前言
Vue 和 React 都是业界十分流行的前端框架,Vue给自己的定义是渐进式的JavaScript框架
,React给自己的定义 是一个用于构建用户界面的 JavaScript 库
。从定位上来说就可以初见端倪,Vue 的设计思想是渐进式,也就是说 Vue 可以随着应用的复杂度的而逐步增加 Vue 的能力。尽量使得用户在使用 Vue 时只需要引入自己需要的部分,而不是强行让用户接受完整的Vue能力。React 则是旨在用于构建用户界面,也就是说只负责UI渲染这一层,其他的能力就交给了社区自己选择。没有孰优孰劣,本文通过对常用的Vue的能力和React对比,以达到更好的理解 Vue 和 React 的目的。
# 开发脚手架
Vue使用的是 VueCli (opens new window),使用如下:
# 1.安装
npm install -g @vue/cli
# OR
yarn global add @vue/cli
2
3
# 1.创建项目
vue create project-name
React使用的是 create-react-app (opens new window),使用如下:
# 创建项目
create-react-app
默认可以用npx
命令:
npx create-react-app project-name
# 插槽
Vue使用的是 slot
标签,使用如下:
# 子组件
<div class="son">
<slot></slot>
</div>
2
3
# 父组件
<div class="parent">
<son>这里的内容会展示在默认插槽中</son>
</div>
2
3
React 中没有插槽的概念,使用children
实现类似插槽的效果:
父组件
import React, { Component, Fragment } from 'react'
import ReactDOM from 'react-dom'
class Title extends Component {
render () {
return (
<h1>欢迎进入{this.props.children}的世界</h1>
)
}
}
const Content = (props) => {
return (
<p>{props.children}</p>
)
}
class App extends Component {
render () {
return (
<Fragment>
<Title>React</Title>
<Content><i>React.js</i>是一个构建UI的库</Content>
</Fragment>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Vue中的插槽概念很多,比如动态插槽、具名插槽、插槽作用域。React中都是使用children
属性实现。
# 组件定义
Vue 中书写组件使用 单文件组件SFC (opens new window),类似于这样:
<template>
<div>
<h1>Hello World!</h1>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
2
3
4
5
6
7
8
9
10
11
组件模版写在template
中,组件逻辑写在script
中,组件样式写在style
中。
React 中定义组件则是使用JSX (opens new window),分别提供了两种写法:类组件和函数式组件。
# 1.类组件
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
render () {
return (
// 注意这里得用this.props.name, 必须用this.props
<h1>欢迎进入React的世界</h1>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 2.函数式组件
import React from 'react'
import ReactDOM from 'react-dom'
const App = () => <h1>欢迎进入React的世界</h1>
ReactDOM.render(
// React组件的调用方式
<App />,
document.getElementById('root')
)
2
3
4
5
6
7
8
9
10
可以看到,React 中的用法更贴近原生JS,对开发者很友好,但是JSX
有一定的学习成本。Vue中使用 SFC
定义组件,贯彻了逻辑、模版、样式分离的思想,代码可读性较好。
# 组件通信
Vue中组件通信的方式有:
- Prop/ $emit
- Provide / inject
- Ref
- Vuex
- 插槽
- EventBus
- $attrs和$listeners
# 组件样式隔离
Vue中的样式隔离官方提供了 scoped
属性,非常友好
<style scoped>
</style>
2
3
这样每一个组件的样式都被隔离在单独的作用域中,避免产生组件样式污染。
React中样式官方没有给处解决方案,但是推荐使用行内样式。但是行内样式似乎违背了样式和结构分离的思想。于是社区就提出了好几种样式隔离的方案,比如 classnames (opens new window) 和 css-in-js (opens new window)
# classnames
其实就是通过生成全局唯一的类名来避免样式污染,并且该库也支持动态class。使用如下:
import React from 'react'
import ReactDOM from 'react-dom'
const classNames = require('classnames');
const myClass = classNames({
'activeColor': 'red',
});
const App = () => <h1 className={ myClass }>欢迎进入React的世界</h1>
ReactDOM.render(
// React组件的调用方式
<App />,
document.getElementById('root')
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
注意
为了避免和JavaScript中的class关键字同名,类名需要使用 className
# CSS in JS
说白了就是js中书写css,简单的使用如下:
在样式文件style.js
中定义:
import styled from 'styled-components'
export const DemoStyleWapper = styled.div`
myClass {
'activeColor': red
}
}
2
3
4
5
6
7
组件中
import React from 'react'
import ReactDOM from 'react-dom'
import { DemoStyleWapper } from 'style.js'
const App = () => <DemoStyleWapper><h1 className={ myClass }>欢迎进入React的世界</h1></DemoStyleWapper>
ReactDOM.render(
// React组件的调用方式
<App />,
document.getElementById('root')
)
2
3
4
5
6
7
8
9
10
从这里看出,Vue提出的 scoped
用法简直就是前端开发者的福音,React 官方没有给出样式隔离的官方解决方案也是蛋疼。