前言
最近两周学习了一下 React
,使用起来是真香。Vue
和 React
具体的区别可以看下,Vue官方文档。实际上他们相同的地方还挺多的,使用者在从vue过渡到react一定很多不适应的地方,但是一提到这个其实就是vue的那什么什么,相信会更好的理解。
本文不负责讲解具体的react/vue教程,只是列举各自的api进行对比。
模板
Vue一般使用脚手架vue-cli,其每个小的组件是一个独立的 *.vue
文件,而React的每个组件都是一个函数或者一个class,文件格式一般是 *.js
或者 *.jsx
。
// vue 组件
<template>
<div>我是一个vue组件</div>
</temlate>
// react
import React, { Component } from 'react'
// 函数组件
const Demo = () => <div>我是一个react组件</div>
// class组件
class Demo extends Component {
render() {
return <div>我是一个react组件</div>
}
}
data 和 state
Vue里的所有值都是写在 data
中,react 是通过 state 初始化数据,在 hooks 中通过 useState 来定义。另外定义的值在模板中渲染时,vue 是 {{}} 包裹,react使用的是 jsx语法,使用 {} 包裹。更新数据时,vue由 对象属性进行更新,即直接在data中定义,更新数据时直接赋值修改,在react中,组件内的数据都通过状态管理即state,state不能直接修改,而是通过 setState的方式更新。
// vue 组件
<template>
<!-- 用的双花括号的方式声明式渲染,这里可以看到模板内注释的方法也不一定哦 -->
<div>{{name: 'slash'}}</div>
</template>
export default {
data() {
return (
name: 'slash'
)
},
created() {
// 三秒后 name的值修改
setTimeout(() => {
this.name = 'name changed'
}, 3000)
}
}
// react 组件
import React, { Compontent, useState, useEffect } from 'react'
// class式
class Demo extends Compontent {
constructor(props) {
super(props)
this.state = {
name: 'slash'
}
}
componentDidMounted() {
setTimeout(() => {
// react的setState是异步的,所以建议使用函数式的更新
this.setState(() => {
return {
name: 'name changed'
}
})
}, 3000)
}
render() {
const { name } = this.state
return (
<div>{name}</div>
)
}
}
// hooks函数式
const Demo = () => {
const [name, changeName] = useState('slash')
// hooks 的写法中 useEffect表示生命周期,具体内容可以看官网文档
useEffect(() => {
changeName('name changed')
return () => {}
}, [])
return (
<div>{name}</div>
)
}
生命周期
通过上面的代码可以看到 react 和 vue 一样也有自己的生命周期,各自对应的内容:
vue | react |
---|---|
beforeMount | componentWillMount |
mounted | componentDidMount |
beforeUpdate | componentWillUpdate |
updated | componentDidUpdate |
beforeUpdate | componentWillUnmount |
beforeDestroy | componentWillUpdate |
指令
在Vue中有很多指令,比如 v-if
v-for
等等,React中没有指令的概念,条件判断和循环都是使用js的原生代码完成。
// vue的循环渲染和条件判断
<template>
<div>
<!-- 只渲染单数的list -->
<p
v-for="item in list"
key="item"
v-if="item % 2 === 1">
{{item}}
</p>
</div>
</template>
export default {
data() {
list: [1, 2, 3, 4, 5]
}
}
// react的循环渲染和条件判断
import React, { useState } from 'react'
const Demo = () => {
const [list] = useState([1, 2, 3, 4, 5])
return (
<div>
{/* jsx语法中只要用js的就用一个花括号括起来 */}
{
list.map(item => <p key={item}>{item}</p>)
}
</div>
)
}
通信
vue的子父组件通信,使用的是 props 和 $on
监听 $emit
派发的事件。在React中是通过 props 的执行回调来进行通信。
// vue 组件
// child组件
<template>
<div>
<p>name is {{name}}</p>
<button @click="send"></button>
</div>
</template>
export default {
props: {
name: {
type: String,
default: ''
}
},
methods: {
send() {
this.$emit('send', '这里是要通信的参数值')
}
}
}
// father组件
<template>
<div>
<p>children 传给我的值 {{message}}</p>
<child :name="sendDataToChild" @send="getMessage"/>
</div>
</template>
import child from './child'
export default {
data() {
return {
message: null,
sendDataToChild: '这是要传给子组件name的值'
}
},
methods: {
getMessage(message) {
this.message = message
}
}
}
// react 组件
// 子组件
const Children = props => {
const { name, handleClick } = props
const onClick = () => {
handleClick('传值给父组件')
}
return (
<div>
<p>{name}</p>
<button onClick={onClick}></button>
</div>
)
}
// 父组件
const Father = (props) => {
const handleClick = (message) => {
console.log(message)
}
return (
<div>
<Children name="传给子组件的值" handleClick={handleClick} />
</div>
)
}
插槽
vue中可以通过插槽 slot
预留位置去组合插件,在react中没有插槽的概念,但是可以通过 props 直接插入
// vue组件
// child 组件
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
// father 组件
<template>
<child>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</child>
</template>
// react组件
const Child = (props) => {
const { header, children, footer } = props
return (
<div>
<header>{header}</header>
<main>{children}</main>
<footer>{footer}</footer>
</div>
)
}
const Father = () => {
return (
<Child
header={<h1>Here might be a page title</h1>}
footer={<p>Here's some contact info</p>}>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</Child>
)
}
结尾
还有很多其他的使用没有列出来,在后续的学习中会将内容逐步更新,谢谢阅读,如有错误的地方,可以在评论中指出和讨论,谢谢。