一个tab的选项卡,让你玩转react的更种渲染,以及事件的传参

第一种方法
根据类名来渲染

	// 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

如果上面哪些地方不清楚或者笔误,可以私信我。如果觉得上面总结的好,那就点个赞把。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值