为Vue使用者准备的React学习指南

226 阅读5分钟

前言

最近两周学习了一下 React,使用起来是真香。VueReact 具体的区别可以看下,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>
            
    )
}

结尾

还有很多其他的使用没有列出来,在后续的学习中会将内容逐步更新,谢谢阅读,如有错误的地方,可以在评论中指出和讨论,谢谢。