第一种方法
根据类名来渲染
// import React, { Component } from 'react'
// export default class Tab extends Component
import React from 'react'
import './style.css'
export default class Tab extends React.Component{
constructor(props){
super(props)
this.state={
currentage:'home',
act:'active'
}
}
cli(shij){
// let { currentage } =this.state
this.setState({
currentage:shij
},
// console.log(shij,this.state.currentage,'1221') shij和currentage,会有误差
)
}
render(){
let { currentage,act } =this.state
return(
<div className='tabage'>
<div style={{display:'flex'}}>
<button
// <div style={{display: (index===this.state.currentIndex) ? "block" : "none", color:"red"}}>此标签是否隐藏</div>
// style={{display: ('home' ===currentage) style相当于v-show和v-if
// ? "block" : "none", color:"red"}}
// >
className={'home'===currentage?act:null}
onClick={this.cli.bind(this,'home')}
>
首页
</button>
<button
className={'list'===currentage?act:null}
onClick={this.cli.bind(this,'list')} >列表页</button>
<button
className={'about'===currentage?act:null}
onClick={this.cli.bind(this,'about')}>关于页</button>
</div>
<div className='xiamia'>
{/* 在react中, style中的display,相当于v-if style里面方法的是表达式*/}
<div style={{display:('home'==currentage)?"block":"none"}}>首页</div>
<div style={{display:('list'==currentage)?"block":"none"}}>列表页</div>
<div style={{display:('about'==currentage)?"block":"none"}}>关于页</div>
</div>
</div>
)
}
}
第二种
根据索引渲染
// import React, { Component } from 'react'
// export default class Tab extends Component
import React from 'react'
import './style.css'
export default class Tab extends React.Component{
constructor(props){
super(props)
// state相当于data
this.state={
currentage:'home',
act:'active',
// 上半部分
arr:[
{ id:1,name: '首页' },
{ id:2,name: '列表页' },
{ id:3,name: '关于页' }
],
index1:0,
// 下半部分
arrtwo:[
{ id:1,name: '首页' },
{ id:2,name: '列表页' },
{ id:3,name: '关于页' }
]
}
}
// 定义了方法,要调用
cli(){
// 把数组解构,出来进行遍历
let { arr,index1,act } = this.state
// (ele,index)=>{()} // 里面的不是插值表达式,所以 显示不内容
return arr.map((ele,index)=>(
<div style={{float:"left"}} key={ele.id}>
<button className={index1==index?act:null} onClick={this.handleClick.bind(this,index)}>{ele.name}</button>
</div>
)
)
}
handleClick(index){
// 点击之后,改变索引
this.setState({
// 设置state,里面的状态可以不用把它解构出来
index1:index
})
}
downtwo(){
// 把需要的数据,解构出来 index1主要是控制上面的颜色和下的显示隐藏
let { arrtwo,index1 } = this.state
// 方法中,必须返回一个jsx的语法 map把需要的ele,index,可以拿出来使用
return arrtwo.map((ele,index)=>(
<div className='xiamia' key={ele.id}>
{/* 下面半部分的显示,隐藏 */}
<div style={{display:(index==index1)?"block":"none"}}>{ele.name}</div>
</div>
))
}
render(){
let { currentage,act,arr} =this.state
return(
<div className='tabage'>
{this.cli()}
{/* 如果上半部分和下半部分样式(布局)相同,可以进行复用 */}
{this.downtwo()}
</div>
)
}
}
/*
**
条件渲染的例子**
// 引入react
import React from 'react'
// 引入样式统一,在组件的内部使用
import './style.scss'
// 引入组件 注意单词,不要写错了
/* 因为在Child的index.js的文件中,
第一种方式引入
暴露的方式是 export default Child
import { Child } from '../child'
第二中方式引入,因为是对象的方式暴露
export {
Child
}
对象的方式引入
import Child from '../Child'
*/
import Child from '../Child'
var ele=(
<div>
<h1>jsx</h1>
</div>
)
// 暴露组件
export default class Styles extends React.Component{
// 构造函数
constructor(props){
super(props)
// 定义状态(state)
this.state={
bol:true,
idx:3,
// color:'red',
color: 'red',
dis:'inline-block',
sty: {
color: 'orange',
fontSize: '50px'
}
}
}
// v-if-else 按照符合的数据,进行匹配 定义一个方法,调用这个方法
test(){
// 把数据解构出来 { idx } = { this.state }这种写法是错误的
let { idx } = this.state
var ele= null; // 定义一个空的对象,省的每次return,节省浏览器的性能
switch(idx){
case 1:
ele = (<h1>111111</h1>)
break;
case 2:
ele = (<h1>222222</h1>)
break;
case 3:
ele = (<h1>333333</h1>)
break;
case 4:
ele = (<h1>444444</h1>)
break;
default:
}
// return 返回值
return ele
}
// handleClick(){
// var num= Math.random()
// console.log(num)
// // 点击事件,修改数据
// this.setState({
// color: num > 0.5 ? 'red' : 'pink',
// dis: num > 0.5 ? 'inline-block' : 'none'
// })
// }
changeClass() {
var num = Math.random()
this.setState({
color: num > 0.5 ? 'red' : 'green',
dis: num > 0.5 ? 'inline-block' : 'none'
})
}
// 渲染数据
render(){
// this.state.msg 把它数据解构出来
let { bol, color,dis, sty } = this.state
return (
<div className="Styles">
<p>条件的渲染</p>
{bol&&<div className='box'>这是个div标签</div>}
{/* 数据的渲染用& */}
{bol?<h1>这个是h1的标题</h1>:''}
{/*
Warning: validateDOMNesting(...): <h1> cannot appear as a child of <h1>.
h1不能作为子级标签,直接使用插值jsx语法
*/}
{/* 调用方法,上面定义的方法 */}
{bol?this.test():'数据没有渲染出来'}
{bol?<Child></Child>:'组件没有渲染出来'}
{bol&&ele}
{/* 事件名大写,要定义事件方法 */}
<span className={color}>aaaa</span>
<span className={color}>颜色变</span>
{/* 样式要写成,对象的写法 */}
<span style={{color:'green',display:dis}}>bbb</span>
{/* <button onClick={this.handleClick.bind(this)}>点击改变样式</button> */}
<button onClick={this.changeClass.bind(this)}>改变样式</button>
<div>
<h1 style={sty}>测试动态样式</h1>
</div>
</div>
)
}
}
react的三种事件传参
// 引入react
import React from 'react'
// 引入子组件
import { Child } from '@/components'
/*
类组件
props是父子之间的通信纽带
props是只读
*/
// 暴露组件
// export default class User extends React.Component{
// }
// state 状态
class User extends React.Component{
constructor(props){
super(props) // 继承父类,必须是第一行
// 当state发生变化时,视图自动发生变化(单向数据流)
this.state={
msg:'hello child',
list:[
{id:'1',name:'xi'},
{id:'2',name:'we'},
{id:'3',name:'me'}
],
list1:[
{id:'1',name:'xi'},
{id:'2',name:'we'},
{id:'3',name:'me'}
],
}
// 在这里改变this的指向
this.click3=this.click3.bind(this,'三')
// this是指向User这个类
console.log(this,'this11121212121')
}
// 实列方法
click1(arg,e){
// 注意他们的接受顺序 参数 this e事件
console.log('click1',arg,this,e)
}
click2(arg,e){
// 这里的this,是指向当前的事件源 User
// {props: {…}, context: {…}, refs: {…}, updater: {…}, state: {…}, …}
console.log('click2',arg,this,e)
}
click3(arg,e){
// this那不到是,this的指向是undefined,应该要在类User中,定义
console.log('click',arg,this,e)
}
// 定义一个方法,点击改变,state中的数据
change1(){
// 改变state,是异步操作的,要使用setState
// console.log(this)
this.setState({
msg:'hello world 2020 '
},function(){
console.log('msg改变成功1221')
})
}
// 在外面定义遍历list的方法 第一种写法,渲染数据
initList(){
// 获取数据列表this.state.list,可以通过把它解构出来
let { list } =this.state
var res=list.map(ele=>( // 这里是一条语句,花括号可以省略,如果是多条语句,花括号,不看省略
<div key={ele.id}>
<span>{ele.id}</span>
<span>-</span>
<span>{ele.name}</span>
</div>
))
// index.js:117 Uncaught ReferenceError: ele is not defined
// 一定要把它返回出去
return res
}
// 第二种方法,渲染数据
initList2(){
// 解构出来 this.state.list1
let { list1 } =this.state
var resarr=[]
// 定义一个空的数组,来存储数据 ele后面根表达式
list1.map(ele3=>{
// 做数据的处理,它是会影响list,导致方法一,方法二的,方法三的数据都发生影响,
ele3.id= ele3.id*100
// 把处理好的数据,push后渲染在页面上,所有的数据都发生了变化
resarr.push(
// 设置好key,因为key的值是唯一的
<div key={ele3.id}>
<span>{ele3.id}</span>
<span>-</span>
<span>{ele3.name}</span>
</div>
)
})
// 函数据要有返回值
return resarr
}
// 渲染数据 钩子函数
render(){
// 渲染数据的第三种写法,页面一加在载渲染一次
// 把对象解构出来
let { list } =this.state
// 用res2来接收数据 ele=>() {}大括号写语句
var res2=list.map(ele=>(
// 在大的盒子中设置key,key的作用是唯一的
<div key={ele.id}>
<span>{ele.id}</span>
<span>-</span>
<span>{ele.name}</span>
</div>
))
return(
<div>
<h1>user page</h1>
{/* 下面的是react事件绑定,事件传参数 */}
{/* 事件绑定 this.click1()加括号自动调用事件,
jsx的写法,不加bind 只调用一次 */}
<button onClick={this.click1.bind(this,'一')}>点击事件1</button><br/><br/>
{/* 他们传参数顺序是先参数,后事件 */}
<button onClick={(e)=>this.click2('二',e)}>点击事件2</button><br/><br/>
{/* 注释,一般不这样写 */}
<button onClick={this.click3}>点击事件3</button><br/><br/>
{/* 点击改变,state中的数据,用setState,来改变state中的数据,不能直接修改 */}
{/* Uncaught TypeError: Cannot read property 'setState' of undefined
Uncaught TypeError: Bind must be called on a function
this.change1.bind() 加括号指向
不使用this的指向,它的指向是指undefined
*/}
<button onClick={this.change1.bind(this)}>点击改变msg</button>
{/* 调用子组件,并且把数据传给子组件 ccc是动态的传替 */}
<Child aaa="111" bbb="222" ccc={this.state.msg}></Child>
<div>
{this.initList()}
</div>
<br/>
<br/>
<div>
{this.initList2()}
</div>
<br>
</br>
{/* 页面开始的时候,就渲染render中的数据*/}
<div>
{res2}
</div>
<br/>
<br/>
{/* 第四种方法,渲染用的是jsx,表达式*/}
<div>
{
list.map(ele=>(
<div key={ele.id}>
<span>{ele.id}</span>
<span>-</span>
<span>{ele.name}</span>
</div>
))
}
</div>
</div>
)
}
}
export default User
如果上面哪些地方不清楚或者笔误,可以私信我。如果觉得上面总结的好,那就点个赞把。