使用递归的思路渲染菜单
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>