React类组件 React基础 Day04

使用递归的思路渲染菜单

flat多维数组拍平

css 复制代码
 var arr1 = [1,2,4,5, ['a','b','c',['mk','ml','mp']]]

使用数组中的方法flat对数组进行拍平的处理, flat可以接收一个number类型的参数

scss 复制代码
arr1.flat()  // 默认拍平一次
arr1.flat(2)   //拍平2次, number类型
arr.flat(Infinity)  // 无限拍平

flat有个特点:如果数组中有空数组[],在拍平的时候,可以帮你去掉这个空的数组

less 复制代码
var arr1 = [1,2,4,5, ['a','b','c',['mk','ml','mp']],[]]

 // 数组拍平
var arr2 =  arr1.flat(Infinity)  // 无限拍平数组
console.log(arr2);

flatMap的使用

flatMap和map的使用方式一样, 都是根据原有数组 循环遍历获取到想要的数据结构,唯一不同的是 flatMap在map的基础上做了拍平的工作

什么情况下需要使用flatMap?

需要过滤一些你不想要的数据的时候使用, 相当于有了 filter过滤 + map循环的功能;

完整代码展示:

javascript 复制代码
import React, { Component } from 'react'
import menudata from '../assets/menu'
export default class MenuTest extends Component {

    menuFun = (menus)=>{
       let arr =  menus.flatMap((menu,index)=>{
           if(menu.name){
                return  <li key={index}>
                    <span>{menu.name}</span>
                    {menu.child &&  <ul> { this.menuFun(menu.child) }</ul> }
                </li>
           }  else {
            return []
           } 
        })
        return arr
    }
  render() {
    const menulist = this.menuFun(menudata);
    console.log(menulist);
    return (
      <div>
        <ul>
            {menulist}  
        </ul>
      </div>
    )
  }
}

form表单简单封装

react数据流是单向的, 父给子传值的时候, 子组件不能直接修改,但是 传的是对象,数据 复杂数据类型的时候,可以修改对象的某个属性值

javascript 复制代码
import React, { Component } from 'react'

export default class FormListNew extends Component {
    // react数据流是单向的, 父给子传值的时候, 子组件不能直接修改,
    // 但是 传的是对象,数据 复杂数据类型的时候,可以修改对象的某个属性值
    state = {
        formData:this.props.currentCol
    }
    // 收集form表单数据
    getFormVal = (ev)=>{
        let keyname = ev.target.name,
            value = ev.target.value;
            this.setState({
                formData:{...this.state.formData, [keyname]:value}
            })

    }
    // 提交form表单
    sendForm = (ev)=>{
        ev.preventDefault();  // 阻止form表单默认行为
        console.log(this.state.formData,'form表单数据');
        this.props.send(this.state.formData)   // 相当于调用父组件getFormData这个方法
    }
  render() {
    const {formData} = this.state;
    // 父组件里配置 form表单需要展示的内容
 
    return (
        <form action="">

            <ul>
                <li>
                    <span>拼团商品:</span> <input type="text" name='name' value={formData.name} onChange={this.getFormVal}  />
                </li>
                <li> 
                    <span>原价:</span>   <input type="text" name='price' value={formData.price}  onChange={this.getFormVal} />
                </li>
                <li>
                    <span>拼团价格:</span><input type="text" name='spellPrice'  value={formData.spellPrice} onChange={this.getFormVal}  />
                </li>
                <li>
                    <span>时间:</span> 
                    <input type="datetime-local" name='endTime'  value={formData.endTime} onChange={this.getFormVal} />
                </li>
            </ul>
            <button onClick={this.sendForm}>确定修改</button>
        </form>   
    )
  }
}

如果需要多个页面可以使用这个form表单组件,达到form表单的通用性, 需要在父组件把需要显示的表单项 通过父子组件传值的方式传给form表单,然后通过map循环的方式渲染

form表单优化封装

javascript 复制代码
import React, { Component } from 'react'

export default class FormList extends Component {
    // react数据流是单向的, 父给子传值的时候, 子组件不能直接修改,
    // 但是 传的是对象,数据 复杂数据类型的时候,可以修改对象的某个属性值
    state = {
        formData:this.props.currentCol
    }
    // 收集form表单数据
    getFormVal = (ev)=>{
        let keyname = ev.target.name,
            value = ev.target.value;
            this.setState({
                formData:{...this.state.formData, [keyname]:value}
            })

    }
    // 提交form表单
    sendForm = (ev)=>{
        ev.preventDefault();  // 阻止form表单默认行为
        console.log(this.state.formData,'form表单数据');
        this.props.send(this.state.formData)   // 相当于调用父组件getFormData这个方法
    }
  render() {
    const {formData} = this.state;
    
    return (
        <form action="">
            <ul>
                {this.props.formOption.map((option)=>{
                    return  (<>
                    {option.type=='text' && <li>
                            <span>{option.label}:</span> <input type="text" name={option.name} value={formData[option.name] ||''} onChange={this.getFormVal}  />
                        </li>}

                    {option.type=='datetime' && <li>
                            <span>{option.label}:</span> <input type="datetime-local" name={option.name} value={formData[option.name] ||''} onChange={this.getFormVal}  />
                        </li>}    
                    </>)
                    
                   
                })}

              
            </ul>
            <button onClick={this.sendForm}>确定修改</button>
        </form>   
    )
  }
}

页面中使用

表单配置项

go 复制代码
const formOption = [{
    label:'拼团商品',
    type:'text',
    name:'name'
},{
    label:'原价',
    type:'text',
    name:'price'
},{
    label:'拼团价格',
    type:'text',
    name:'spellPrice'
},{
    label:'时间',
    type:'datetime',
    name:'endTime'
}]
xml 复制代码
<FormList send={this.getFormData} currentCol={currentData} formOption={formOption}></FormList>

分页组件的封装

思路: 通过给分页组件传每页显示条数pageSize, 当前第几页PageIndex, 总共条数total 这3个字段, 然后在组件里进行处理, 当点击页码 和 每天显示多少条的选项时候, 给父组件传值(pageIndex,pageSize)

分页组件:

javascript 复制代码
import React, { Component } from 'react'
import style from './page.module.scss'
export default class PageNumber extends Component {

    get totalPage(){
        return Math.ceil(this.props.total/this.props.pageSize)
    }
    // 页码
   getPageNum=()=>{
    let arrPage = [];
    for(let i=1;i<=this.totalPage;i++) {
        arrPage.push(<span key={i} onClick={()=>this.updatePage('pageIndex',i)}>{i}</span>)
    }
    return arrPage;
   }
   // 事件处理  , 改变每页显示多少条数据 , pageIndex, pageSize的改变
   updatePage = (kind,ev)=>{
    let value = (typeof ev == 'number') ? ev : ev.target.value;
    this.props.sendPage({
        [kind]:value
    }) 
     // 相当于执行父组件getPageData这个方法
    // {
    //     pageSize:value
    // }

   }

  render() {
    const {pageIndex,pageSize} = this.props;
    
    return (
        <div className={style['page-number']}><span>你当前在{pageIndex}页 </span>
        <span>总共有{this.totalPage}页</span>
        <span className={style['num']}>每页显示:
        <select name="" id="" value={pageSize} onChange={(ev)=>this.updatePage('pageSize',ev)}>
            <option value="2">2</option>
            <option value="5">5</option>
            <option value="10">10</option>
        </select>
    </span>
<div className={style['pageing']}>
    {this.getPageNum()}
</div>
</div>
    )
  }
}

使用分页组件

arduino 复制代码
 state = {
        pageObj:{
            pageIndex:1,   //当前页面
            pageSize:5,  // 每页显示的条数
            total:0   // 总共有多少条数据
        }
    }
javascript 复制代码
    getTicketList = async () => {
        const {pageIndex,pageSize} = this.state.pageObj;
        console.log({pageIndex,pageSize},'分页数据');
        // await 后面必须跟 promise对象
        let resData = await axiosEl({
            url: '/test/ticket',
            method: 'post',
            data:{pageIndex,pageSize}
        })
        this.setState({
            goodList: resData.tempList,
            pageObj:{...this.state.pageObj,total:resData.tempList.length}
        })

    }
kotlin 复制代码
    // 获取分页的数据
    getPageData = (data)=>{
        console.log(data,'获取子组件分页数据');
        // 更新pageObj
        this.setState({
            pageObj:{...this.state.pageObj, ...data}
        },()=>{
            // 开始调分页接口
            this.getTicketList();
        })
        
    }
ini 复制代码
     {/* 做分页:
       1. 当前在第几个 pageIndex
       2. 每页显示多少条数据  pageSize
       3. 总共有多少条数据  total */}
                <PageNumber 
                    pageIndex={pageObj.pageIndex}
                    pageSize={pageObj.pageSize}
                    total={pageObj.total}
                    sendPage={this.getPageData}
                ></PageNumber>
相关推荐
前端百草阁12 分钟前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜12 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40413 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish14 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple14 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five15 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序15 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54116 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
酷酷的威朗普17 分钟前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5
前端每日三省17 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript