注明:本文中所指 Vue 的版本是Vue2, React 的版本是 React17
1、Jsx和template
在Vue2中是使用template的,这点使用 Vue 的同学们都知道,而在 React 中使用的是JSX,JSX是一个看起来很像 XML 的 JavaScript 语法扩展。
它有以下优点:
- JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
- 它是类型安全的,在编译过程中就能发现错误。
- 使用 JSX 编写模板更加简单快速。
JSX的例子:使用ReactDOM.render函数,将DOM渲染到对应到id为app的节点下
// 使用ReactDOM.render函数,将DOM渲染到对应到id为app的节点下ReactDOM.render( <div> <h1>前端真的很难</h1> <h2>前端真的很忙</h2> <p>前端真的啥都要学</p> </div> , document.getElementById('app'));
2、React 中给元素设置 style
React 使用内联样式。我们可以使用 驼峰法 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了给 h1 元素添加 myStyle 内联样式:
function Demo() { let myStyle = { fontSize: 100, // 驼峰法 color: '#FF0000' } return <h1 style={myStyle}>给h1元素添加内联样式</h1>}
3、React 中给元素设置 class
由于 JSX 就是 JavaScript,一些标识符像 class 不建议作为 XML 属性名。作为替代,使用 className来做对应的属性。
function Demo() { const classes = 'message info success' return ( <div> <h1 className='message'>添加单个样式类</h1> <h1 className='message info'>添加多个个样式类</h1> <h1 className={classes}>使用值来当做class</h1> </div> )}
4、React 中的点击事件
在Vue中的点击事件使用的是@click来触发的,而在JSX中使用的是onClick
function Demo() { const handleClick = () => { console.log('点击事件触发') } return ( <button onClick={handleClick}>点我</button> )}
5、React 中修改值触发DOM更新
我使用的是React hook其中的useState,这一个hook在修改常量的时候比较简单,但是在修改引用对象或者数组的时候就需要先进行浅拷贝再进行覆盖修改
import { useState } from 'react'function Demo() { const [msg, setMsg] = useState('一坨数据') const [obj, setObj] = useState({ name: '隔壁老王', food: '泡面' }) const [arr, setArr] = useState([ { message: '今天要干嘛', id: 1 }, { message: '今天要摸鱼', id: 2 }, { message: '明天也摸鱼', id: 3 } ]) const handleClick = (type: number) => { switch (type) { case 1: setMsg('我讨厌隔壁老王') // 直接赋值 break; case 2: setObj({ ...obj, food: '牛肉丸', }) // 浅拷贝 break; case 3: setArr([...arr, { message: '明天是周末', id: 4}]) // 浅拷贝实现push效果 break; } } return ( <div> <button onClick={() => handleClick(1)}>修改msg</button> <button onClick={() => handleClick(2)}>修改obj的food</button> <button onClick={() => handleClick(3)}>arr添加一项</button> <h1>{msg}</h1> <p>{`我是${obj.name}我喜欢吃${obj.food}`}</p> <ul> { arr.map(({ message, id }) => { return <li key={id}>{message}</li> }) } </ul > </div> )}
6、生命周期
使用React的hook——useEffect
import { useState, useEffect } from 'react'function App() { const [num, setNum] = useState(1) const [count, setCount] = useState(1) useEffect(() => { console.log('啦啦啦') }) return ( <div> <button onClick={() => setNum(num + 1)}>点我修改num</button> <button onClick={() => setCount(count + 1)}>点我count</button> </div> )}
第二个参数不传
useEffect(() => { console.log('啦啦啦') })
当useEffect第二个参数不传时,页面初始和数据更新的时候,第一个参数函数都会执行,所以此时初始页面时会输出一次啦啦啦,然后无论你点修改num或者修改count的按钮时,也都会输出啦啦啦
第二个参数传递空数组
useEffect(() => { console.log('页面初始化') }, [])
当useEffect第二个参数传[]时,那么第一个参数函数只有在页面初始的时候才会执行,也就是只执行一次,无论你点修改num或者修改count的按钮,都不会执行这个函数
第二个参数传递非空数组
// 第一种情况 useEffect(() => { console.log('哈哈哈哈') }, [num]) // 第二种情况 useEffect(() => { console.log('哈哈哈哈') }, [count]) // 第三种情况 useEffect(() => { console.log('哈哈哈哈') }, [num, count])
当useEffect第二个参数传非空数组时,页面初始和依赖的数据发生更新的时候,第一个参数函数都会执行。比如上方的例子:
- ①、只有修改num按钮时,才会再次输出哈哈哈哈
- ②、只有按修改count按钮时,才会再次输出哈哈哈哈
- ③、无论按哪个按钮都会再次输出哈哈哈哈
return清除操作
useEffect(() => { const timeId = setTimeout(() => console.log('我是定时器'), 1000) return () => clearTimeout(timeId) })
React 会在组件卸载的时候执行清除操作。effect 在每次渲染的时候都会执行。React 会在执行当前 effect 之前对上一个 effect 进行清除。
实在不理解的同学,可以疯狂点击按钮,看看我是定时器这句话会输出多遍还是只输出一遍,就恍然大悟了
7、React 中实现 v-if & v-else
Vue中的v-if和v-else
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true 值的时候被渲染。
<h1 v-if="show">show是true是可显示</h1>
也可以用 v-else 添加一个其他模块:
<h1 v-if="show">你看的见我</h1><h1 v-else>你看不见我</h1>
React中实现
如果单单只想实现v-if的话,可以借助&&逻辑运算符
import { useState } from 'react'function Demo() { const [show, setShow] = useState(false) const changeShow = () => { setShow(!show) } return ( <div> {show && <h1>你看的见我</h1>} <button onClick={changeShow}>点我</button> </div> )}
如果想实现v-if和v-else的话,可以借助三元运算符
import { useState } from 'react'function Demo() { const [show, setShow] = useState(false) const changeShow = () => { setShow(!show) } return ( <div> {show ? <h1>你看的见我</h1> : <h1>你看不见我</h1>} <button onClick={changeShow}>点击</button> </div> )}
8、React 中实现 v-show
Vue 中的 v-show
另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:
<h1 v-show="show">林三心是菜鸟</h1>
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS property display。
React中实现
其实就是改变元素的display这个样式来实现效果
function Demo() { const [show, setShow] = useState(false) const changeShow = () => { setShow(!show) } return ( <div> <h1 style={{display: show ? 'block': 'none'}}>你看的见我</h1> <button onClick={changeShow}>点我</button> </div> )}
9、React 中实现 v-for
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数组,而 item 则是数组的每一项的别名。
Vue中的v-for
<ul> <li v-for="item in items" :key="item.message"> {{ item.message }} </li></ul>
React中实现
JSX 允许在模板中插入数组,数组会自动展开所有成员:
function Demo() { const arr = [ <li key={1}>第一项</li>, <li key={2}>第二项</li>, <li key={3}>第三项</li>, ] return ( <ul> {arr} </ul > )}
但是我大多数情况会使用数组的map方法来协助渲染
function Demo() { const arr = [ { message: '第一项', id: 1 }, { message: '第二项', id: 2 }, { message: '第三项', id: 3 } ] return ( <ul> { arr.map(({ message, id }) => { return <li key={id}>{message}</li> }) } </ul > )}
10、React 中实现 computed
Vue 中的 computed
只要name或者food改变,mag会更新成相应的值
<h1>{{msg}}</h1>computed: { msg() { return `我是${this.name},我爱吃${this.food}` } }
React中实现
在 React 中需要通过useMemo这个 hook 来来实现computed的效果
import { useState, useMemo } from 'react'function Demo() { const [name, setName] = useState('隔壁老王') const [food, setFood] = useState('泡面') // 实现computed的功能 const msg = useMemo(() => `我是${name},我爱吃${food}`, [name, food]) // 监听name和food这两个变量 const handleClick = (type: number) => { if (type === 1) { setName('老王') } else if (type === 2) { setFood('牛肉丸') } } return ( <div> <button onClick={() => handleClick(1)}>修改name</button> <button onClick={() => handleClick(2)}>修改food</button> <h1>{msg}</h1> </div> )}
11、React 中实现 watch
// useWatch.tsimport { useEffect, useRef } from 'react'type Callback<T> = (prev?: T) => voidinterface Config { immdiate: Boolean}const useWatch = <T>(data: T, callback: Callback<T>, config: Config = { immdiate: false }) => { const prev = useRef<T>() const { immdiate } = config const inited = useRef(false) const stop = useRef(false) useEffect(() => { const execute = () => callback(prev.current) if (!stop.current) { if (!inited.current) { inited.current = true immdiate && execute() } else { execute() } prev.current = data } }, [data]) return () => stop.current = true}export default useWatch
import { useState } from 'react'import useWatch from '/@/hooks/web/useWatch'function App() { const [num, setNum] = useState(1) useWatch(num, (pre) => console.log(pre, num), { immdiate: true }) return ( <div> <div style={{ color: '#fff' }}>{num}</div> <button onClick={() => setNum(num + 1)}>点我</button> </div> )}
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除