当前位置: 首页 > 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.xdnf.cn/news/1288405.html

相关文章:

  • Flink Python API 提交 Socket 数据源的 WordCount 作业
  • uni-app实战教程 从0到1开发 画图软件 (学会画图)
  • Flutter UI Kits by Olayemi Garuba:免费开源的高质量UI组件库
  • nvm install 14.21.3 时npm 无法下载和识别
  • -bash: ./restart.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录
  • 1.Ansible 自动化介绍
  • 串口通信“第二次总超时”的复盘
  • ETCD备份
  • aspose word for java 使用书签进行内容填充和更新
  • SM4对称加密算法的加密模式介绍
  • Python Day28 HTML 与 CSS 核心知识点 及例题分析
  • 自动驾驶 HIL 测试:构建 “以假乱真” 的实时数据注入系统
  • 《嵌入式Linux应用编程(四):Linux文件IO系统调用深度解析》
  • GraphQL 原理、应用与实践指南
  • 【Altium designer】快速建立原理图工程的步骤
  • Day05 店铺营业状态设置 Redis
  • MySQL-多表查询
  • 第23章,景深:技术综述
  • 下一代防火墙技术
  • 【KO】android 面试 算法
  • 数字气压传感器,筑牢汽车TPMS胎压监测系统的精准感知基石
  • 西门子S7-200与S7-1200通过PPI以太网模块通讯,赋能汽车制造行业发展
  • 如何在 Ubuntu 24.04 LTS Linux 中安装 JSON Server
  • WebAssembly的原理与使用
  • 前端最新Vue2+Vue3基础入门到实战项目全套教程,自学前端vue就选黑马程序员,一套全通关!笔记
  • Tauri Qt孰优孰劣
  • 计算机毕设不知道选什么题目?基于Spark的糖尿病数据分析系统【Hadoop+Spark+python】
  • 数据结构 二叉树(2)堆
  • 91、23种经典设计模式
  • AI大模型基础:BERT、GPT、Vision Transformer(ViT)的原理、实现与应用