当前位置: 首页 > news >正文

11. React组件插槽用法

4. React组件插槽用法

  • 4.1. React中的插槽(Slot)
      1. 在开发中,我们抽取一个组件,但是为了让这个组件具备更强的通用性,我们不能将组件中的内容限制为固定的div、span等等这些元素

      在这里插入图片描述

      1. 这种需求在Vue当中有一个固定的做法是通过slot来完成的,React呢?
      • 在React中是没有插槽的概念的,或者说React中不需要插槽,因为React太灵活了,React中可以通过多种形式来实现插槽的效果,例如可以传递任意属性给子组件
      1. React对于这种需要插槽的情况非常灵活,有两种方案可以实现:
      • 组件的children子元素
      • props属性传递React元素`;
  • 4.2. children实现插槽
      1. 每个组件之间都可以获取到props.children属性:它包含组件的开始标签和结束标签之间的内容
      1. 示例代码如下:
      • 如图:
        在这里插入图片描述

      • 父组件代码:

      // React中是没有插槽的概念的,或者说React中不需要插槽,因为React太灵活了,React中可以通过多种形式来实现插槽的效果,例如可以传递任意属性给子组件
      import React, { Component } from 'react'
      import NavBar from './nav-bar'export class App extends Component {render() {// NavBar实例对象 -> this// this.props.children -> [button, h2, i]return (<div><NavBar><button>按钮</button><h2>我是标题</h2><i>我是斜体字</i></NavBar></div>)}
      }// function createElement(type, props, children) {
      //   children -> arguments.length - 2
      // }export default App
      
      • 子组件代码:
        import React, { Component } from 'react'import './style.css'import PropTypes from 'prop-types'export class NavBar extends Component {render() {const { children } = this.props// 子元素放多个的时候,children是一个数组,一个的时候是一个对象console.log('children===', children)return (<div className='nav-bar'><div>{children}</div> {/* <div className="left">{children[0]}</div><div className="center">{children[1]}</div><div className="right">{children[2]}</div> */}</div>)}}NavBar.propTypes = {children: PropTypes.array}export default NavBar
      
  • 4.3. props实现插槽
      1. 通过children实现的方案虽然可行,但是有以下两个弊端:
      • children的弊端
        • children可能是一个元素也可能是数组,使时需要慎重
        • children对索引顺序要求太高,通过索引值获取传入的元素很容易出错不能准确的获取传入的元素
      1. 另外一种方案就是使用props实现
      • 通过具体的属性名,可以让我们在传入和获取时更加的精准
      1. 实例代码如下:
      • 父组件代码如下:
        // React中是没有插槽的概念的,或者说React中不需要插槽,因为React太灵活了,React中可以通过多种形式来实现插槽的效果,例如可以传递任意属性给子组件import React, { Component } from 'react'import NavBar from './nav-bar'import NavBarTwo from './nav-bar-two'export class App extends Component {render() {// NavBar实例对象 -> this// this.props.children -> [button, h2, i]const btn = <button>按钮</button>return (<div>{/* 1.吃用children实现插槽 */}<NavBar><button>按钮</button><h2>我是标题</h2><i>我是斜体字</i></NavBar>{/* 2.使用props现插槽实 */}{/* 推荐使用props方案,children有点不可控 */}<NavBarTwostyle={{marginTop: '20px'}}leftSlot={ btn }centerSlot={ <h2>呵呵呵呵</h2>  }rightSlot={ <i>斜体2</i> }/></div>)}}// function createElement(type, props, children) {//   children -> arguments.length - 2// }export default App
      
      • 子组件代码如下:
        import React, { Component } from 'react'export class NavBarTwo extends Component {render() {const { leftSlot, centerSlot, rightSlot } = this.propsreturn (<div className='nav-bar'><div className="left">{leftSlot}</div><div className="center">{centerSlot}</div><div className="right">{rightSlot}</div></div>)}}export default NavBarTwo
      
  • 4.4. 作用域插槽实现
      1. 作用域插槽案例;现在子组件的item都是span,希望子组件的内容是根据父组件传进来的类型渲染
    • 父组件代码:

        import React, { Component } from 'react'import TabControl from './TabControl'export class App extends Component {constructor() {super()this.state = {titles: ['流行', '新款', '热门'],tabIndex: 0}}tabClick (index) {this.setState({tabIndex: index})}getTabItem (item) {if(item ==='流行') {return <span>{item}</span>} else if(item === '新款') {return <button>{item}</button> } else {return <i>{item}</i>}}render() {const { titles,tabIndex } = this.state// 现在子组件的item都是span,希望子组件的内容是根据父组件传进来的类型渲染// 作用域插槽return (<div className='app'><TabControl titles={ titles } tabClick={i => this.tabClick(i)}// itemType={(item) => <button>{item}</button>}/>itemType={(item) => this.getTabItem(item)}/><h2>{titles[tabIndex]}</h2></div>)}}export default App
      
    • 子组件代码:

      import React, { Component } from 'react'
      import './style.css'export class TabControl extends Component {constructor() {super()this.state = {currentIndex: 0}}changeTab (index) {this.props.tabClick(index)this.setState({currentIndex: index})} render() {const { titles, itemType } =  this.propsconst { currentIndex } = this.statereturn (<div><div className="tab-control">{titles.map((item, index) => {return (<div className={`item ${currentIndex === index ? 'active' : ''}`} key={index}onClick={(e) => this.changeTab(index)}>{/* <span className='text'  >{item}</span> */}{itemType(item)}</div>)})}</div></div>)}
      }export default TabControl
      
http://www.dtcms.com/a/327066.html

相关文章:

  • 解决 VSCode 无法从右键菜单“通过 Code 打开”文件夹的问题
  • 使用Gradle手搓一个Kotlin/Native项目
  • Nginx 架构和安装
  • Node.js 精选:50 款文件处理与开发环境工具库
  • Mocha在Node.js中的详细使用
  • 阿里云 Windows 服务器 搭建 Gitea 私有 Git 服务器完整教程
  • 云原生高级——nginx
  • 【网站深入seo方法】
  • [论文阅读] (41)JISA24 物联网环境下基于少样本学习的攻击流量分类
  • 记录docker使用kong consul postgresql配置dns异常解决
  • 从零开始手搓一个GPT大语言模型:从理论到实践的完整指南(一)
  • 大数据技术入门精讲(Hadoop+Spark)
  • 数据可视化交互深入理解
  • 五、Elasticsearch在Linux的安装部署
  • 【unity实战】使用Splines+DOTween制作弯曲手牌和抽牌动画效果
  • 计算机网络2-2:物理层下面的传输媒体
  • -bash: ll: 未找到命令
  • 一,设计模式-单例模式
  • 在IDEA中设置SQL解析作用域解决无法解析表的问题(详细图解)
  • 《量子雷达》第1章预习2025.8.12
  • C语言(03)——斐波那契数列的理解和运用(超详细版)
  • 实验-vlan实验
  • C#教程之NPOI读写excel文件XLS,XLSX格式
  • QT第五讲-控件QLineEdit、QSpinBox、QSlider、QScrollBar、QDial、QProgressBar、QLCDNumber
  • MySQL 索引:索引为什么使用 B+树?(详解B树、B+树)
  • 【K8s】K8s控制器——复制集和deployment
  • MySql——B树和B+树区别(innoDB引擎为什么把B+树作为默认的数据结构)
  • 请写一下快速排序算法
  • 多路转接之epoll 【接口】【细节问题】【LT与ET模式】【Reactor】
  • 学习日志32 python