react 和 vue 的比较
比较 | vue |
react ( |
点击事件和类的命名 |
<div @click="toclick" class='btn'></div>
|
<div className="img-wrap" onClick={() => this.toMv(item.id)}>
或者<div className="img-wrap" onClick={this.click}> click=()=>{this.toMv(item.id)}
|
动态添加类名 |
:class={aaa:this.aa === 2}
|
动态添加单类名: <div className={index===1?'active':null}> </div>
已经有类名,在动态添加类名: <div className={ `box${classA}${index===1?‘active’:null }` } ></div>
或者:<div className={ [ classA,'box',index===1? ‘active’:null ].join(' ') } ></div> join() 方法用于把数组中的所有元素放入一个字符串。
|
更改数据 | this.data = '123' 或者 数组 $set |
|
条件选择 | v-if v-else-if v-else | if(){return ...}else{return ...} // this.a?(return ...):(return ...) // this.a&&console.log(123444) |
列表渲染 | v-for=(item,index) in list | this.list.map(item=>{<li key={item.id}>{item.name}<li> }) map遍历谁,就要给谁加key |
样式处理 | 动态添加类名: :class={redColor:this.ee===2} |
行内样式 <div style={{'color:'red','backgroundColor':'pink'}}>233<div>
类名: <div className='aaaa' style={{'color:'red','backgroundColor':'pink'}}>233<div> .aaaa{ text-align: center} |
组件创建 方式 |
1.使用函数创建组件 (函数名称首字母大写,函数组件必须有返回值,返回值为null,表示不渲染) function Hello(){return ( <div>这是第一个函数组件</div>)} 2.类组件 使用es6的语法创建的组件(类首字母大写,类组件要继承React.Component父类,可以使用父类提供的方法或者属性,必须提供render方法及返回值) class Hello extends React.Component{ render(){ return (<div>这是第一个类组件</div>) } } |
|
事件处理 | @加事件名字 |
on+事件名称 = 事件处理函数 onClick= function(){} 事件命名采取驼峰命名 export default class extends React.Component { 类组件与函数组件绑定事件是差不多的,只是在类组件中绑定事件函数的时候需要用到this,代表指向当前的类的引用,在函数中不需要调用this |
事件对象 | 类似 | 通过事件处理函数的参数获取到的事件对象 e e.nativeEvent e.preventDefault() 取消事件的默认动作。 e.stopPropagation() 阻止事件冒泡 |
State SwtState | 无 |
state 是数据,是组件里面的私有数据,只能在组件内部使用,通过this.state来获取状态 export default class extends React.Component { constructor(){ super() // 第一种初始化方式 this.state = { count : 0 } } // 第二种初始化方式 state = { count:1 } render(){ return ( <div>计数器 :{this.state.count}</div> ) } }
setState 修改状态 this.setState({要修改的数据}) 作用修改state 更新ui |
事件绑定this指向 |
1.利用箭头函数自身不绑定this的特点 即绑定事件使用箭头函数 2.使用bind 更改this里面的指向 使用函数 需要使用bind改变this class App extends React.Component { constructor() { super() ... // 通过bind方法改变了当前函数中this的指向 this.onIncrement = this.onIncrement.bind(this) } // 事件处理程序 onIncrement() { ... } render() { ... } }
|
|
受控组件 | 无 v-model双向绑定 |
受控组件:值受到react控制的表单元素 state添加一个值,绑定表单里面的value值,然后通过给表单绑定change事件,设置state的值 inputChange(e){ let target = e.target; let value = target.type == 'checkbox' ? target.checked : target.value; // 如果类型是checkbox,表示改变是否被选中,true,false this.setState({ [e.target.name]: value }) } <input type="text" value={this.state.txt} name="txt" onChange={this.inputChange}/> <input type="checkbox" value={this.state.isChecked} name="isChecked" onChange={this.inputChange}/>
|
非受控组件 | this.$ref 来获取dom节点 |
借助于ref,使用元素DOM方式获取表单元素值 ref的作用:获取DOM或者组件 class App extends React.Component { constructor(){ super() //创建 ref this.txtRef = React.createRef() } // 获取文本框的值 getTxt =() => { console.log(this.txtRef.current.value) } render(){ return ( <div> <input type ="text" ref={this.txtRef} /> <button onClick ={this.getTxt}>获取值</button> </div> ) }
|
案列:渲染评论列表 |
import React, { Component } from "react"; import "./index.scss"; class index extends React.Component { state = { comments: [ { id: 1, name: "jack", content: "沙发!!!" }, { id: 2, name: "rose", content: "板凳~" }, { id: 3, name: "tom", content: "楼主好人" }, ], comment: "", sName: "", }; changeValue = (e) => { this.setState({ [e.target.name]: e.target.value, }); }; topinglin = () => { let {sName,comment} = this.state if(sName.trim()===''|| comment.trim()===''){ alert('请输入内容') return } let newArr = [ { id: this.state.comments.length + 1, name: sName, content: comment, },...this.state.comments ] this.setState({ comments: newArr, comment: '', sName:'', }); }; renderList = () => { if (this.state.comments.length === 0) { return <div className="no-comment">暂无评论,快去评论吧~</div>; } else { return ( <ul> {this.state.comments.map((item) => { return ( <li key={item.id}> <h3>{item.name}</h3> <p>{item.content}</p> </li> ); })} </ul> ); } }; render() { return ( <div className="app"> <div> <input className="user" name="sName" type="text" value={this.state.sName} onChange={this.changeValue} placeholder="请输入评论人" /> <br /> <textarea name="comment" className="content" cols="30" rows="10" placeholder="请输入评论内容" value={this.state.comment} onChange={this.changeValue} /> <br /> <button onClick={this.topinglin}>发表评论</button> {this.renderList()} </div> </div> ); } } export default index;
|
|
传值 |
父--> 子 props 子-->父 $emit 兄弟 bus |
函数组件通过 参数 props接收数据,类组件通过 this.props接收数据 props是只读属性,不能对值进行修改 使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取到props,其他的地方是可以拿到的
父--> 子 父组件提供要传递的state数据 给子组件标签添加属性,值为state中的数据 子组件中通过props接收父组件中传递的数据
子 -- > 父 利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数 父组件提供一个回调函数,用来接收数据 将该函数作为属性的值,传递给子组件 (假设父组件有删除的方法,子组件想调用,需要父组件将方法传过去,子组件接受方法调用)
兄弟组件传值:
|
props进阶 |
props的children属性 :表示组件标签的子节点,当组件标签有子节点后,props就有该属性 children属性与普通的props一样,值可以使任意值(文本、react元素、组件、甚至是函数) |
|
props校验 |
对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据,简单来说就是组件调用者可能不知道组件封装着需要什么样的数据
|
|
生命周期 | 8个 |
组件从被创建到挂载到页面中运行,再到组件不在时卸载的过程 生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数 创建时候: constructor() 创建组件时,最先执行 初始化state 为事件绑定this render() 每次组件渲染都会触发 渲染 UI componentDidMount 组件挂载后(完成DOM渲染后) 发送网络请求 DOM操作 componentDidUpdate 组件更新后 发送网络请求 DOM操作 componentWillUnmount 组件卸载 执行清理工作(比如:清理定时器) |
组件更新机制 |
父组件重新渲染,也会重新渲染子组件,但是只会渲染当前组件子树 |
|
性能优化 | 减轻state 避免不必要的重新渲染 | |
路由 |
安装 yarn add react-router-dom 导入路由的三个核心组件:Router、Route、Link import { BrowserRouter as Router,Route,Link} from 'react-router-dom' 使用Router组件包裹这个应用
使用link组件作为导航菜单 用于指定导航链接(a标签)
使用Route组件配置路由规则和要展示的组件
|
|
|
模糊匹配模式
|