React(一)插槽处理和props
一、插槽
1.插槽的用作
尽可能的让子组件具备更强的复用性,或者说扩展性。
2.插槽的使用场景
1.预设接收是基于传递属性props的方式把相关信息数据值传递给子组件;
2.子组件是需要根据传递过来的【不同的数据值】展示不同的效果;
3.特点
1.封装组件时,要先预留插槽位置,不要写内容;
2.调用组件的时候,要使用双闭合标签,在标签中把插槽信息(子节点信息),传递给组件;
3.组件收到后处理,渲染;
4.注意:当我们通过插槽传入标签节点,它是存在子组件props.children中,并且是虚拟dom的形式。
4.多个子组件传入的插槽数量不一致,如何处理?
例如:
<DemoOne title="我是标题">
//传了两个span
<span>aaaa</span>
<span>vvvv</span>
</DemoOne>
<DemoOne title='服了'>
//传了一个span
<span>heiheih</span>
</DemoOne>
<DemoOne title='hahah'>
//没传任意东西
</DemoOne>
需要
1.处理DemoOne子组件【传递】的插槽数据
2.在DemoOne中我们是可以通过props.children去接受数据
3.渲染插槽数量不一致,不能直接获取的children去写在render函数中
4.React有专门提供的API处理children的问题(React.Children.toAarry),目的是把插槽信息变成数组
例如:
import React from 'react'
const DemoOne = function DemoOne(props) {
let { title,children } = props
children = React.Children.toArray(children)
return (
<div>
{children[0]}
<br />
<h2 className="title">{title}</h2>
<span>{x}</span>
<br/>
{children[1]}
</div>)
}
5.当需要指定插槽位置时,又应当怎么做?
1.首先需要在提供插槽时,给插槽一个属性名,一般叫slot,例如:
<Demo0ne>
<span slot="footer">我是页脚</span>
<span slot="header">我是页眉</span>
</DemoOne>
2.然后依旧是在DemoOne中将数据【处理】后再进行渲染,例如:
import React from 'react'
const DemoOne = function DemoOne(props) {
let { title,children } = props
children = React.Children.toArray(children)
let headerSlot = [],
footerSlot = [],
defaultSlot = [];
children.forEach(child=>{
//子组件插槽进来是虚拟dom,是对象形式即可以在插槽自身的props拿到自身的属性slot
let {slot} = child.props
if(slot=='header){
headerSlot.push(child);
}else if(slot=='footer'){
footerSlot .push(child);
}else{
defaultSlot.push(child);
}
})
return (
<div>
{headerSlot}
<br />
<h2 className="title">{title}</h2>
<span>{x}</span>
<br/>
{footerSlot}
</div>)
}
二、props
1.父传子用props
1.用key:value的方式,写在子组件标签上
2.
1.1 父传子props的底层原理是什么?
1.先通过bebal-process-react-app把子组件标签element格式;
2.再通过createElement把子组件标签创建出一个虚拟dom对象;
3.而虚拟dom对象中会解析出一个props,在props中既有我们传递标签属性(key:value),也有双闭合标签调用时传递的插槽子节点(children) ;
4.传递的标签属性(key:value)和插槽子节点(children),都会默认在子组件中被他的一个型参接受(props);
5.而我们的props是默认做了Object.freeze(props)冻结的,所以props是只读的;
6.如果想要修改,需要把props的值解构出来,赋值给其他的变量,再修改来实现它的更新;
7.虽然不能直接修改,但是可以通过一定的方式对传过的数据进行校验,例如:设置默认值利用
DemoOne.defaultProps = {
title:'我是标题'
}
又获着利用prop-types校验属性和必填项
import PropTypes from 'prop-types'
DemoOne.propTypes = {
title: PropTypes.string.isRequired,
x: PropTypes.number
}
总结一下:无非是【先传值->获取值->处理值->渲染出来】
以上就是插槽和props的全部内容,基本举例的比较简单,只有一两个插槽和基本的属性,真正落实到项目上去操作会比这难很多,思考思考思考,根据具体的需求,理清晰逻辑,梳理数据,动手实现,错了不要紧,冲!