侧边栏壁纸
博主头像
woku博主等级

成功的路上并不拥挤

  • 累计撰写 50 篇文章
  • 累计创建 13 个标签
  • 累计收到 3 条评论

组件组合

woku
2022-04-29 / 0 评论 / 1 点赞 / 179 阅读 / 4,571 字

包含组合(children)

在组件的props中,React会在组件使用时,内部有内容的情况下添加children属性

Container内部有内容,会在props内部添加children属性

  • Container内部是非元素内容,children就是非元素内容
class Container extends React.Component {
  render() {
    console.log(this.props)
    return (
      <div>
        { this.props.children }
      </div>
    )
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <Container>123</Container>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))
  • Container内部是单个元素内容,children就是React元素对象
class Container extends React.Component {
  render() {
    console.log(this.props)
    return (
      <div>
        { this.props.children }
      </div>
    )
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <Container>
          <h2>我是h2</h2>
        </Container>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))
  • Container内部是多个个元素内容,children就是一个数组,里面的每项都是React元素对象
class Container extends React.Component {
  render() {
    console.log(this.props)
    return (
      <div>
        { this.props.children }
      </div>
    )
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <Container>
          <h2>我是h2</h2>
          <p>我是p标签</p>
        </Container>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

image.pngimage.png

属性传递组合

React可以传递任何数据类型,包括React元素

class Container extends React.Component {
  render() {
    console.log(this.props)
    return (
      <div>
        <div className="header">
          { this.props.Header }
        </div>
        <div className="sidebar">
          { this.props.Sidebar }
        </div>
        <div className="main">
          { this.props.Main }
        </div>
      </div>
    )
  }
}
class Header extends React.Component {
  render() {
    return (
      <p>header</p>
    )
  }
}
class Sidebar extends React.Component {
  render() {
    return (
      <p>sidebar</p>
    )
  }
}
class Main extends React.Component {
  render() {
    return (
      <p>main</p>
    )
  }
}
class App extends React.Component {
  render() {
    return (
      <div>
        <Container Header={ <Header/> } Sidebar={ <Sidebar/> } Main={ <Main/> }>
        </Container>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

使用CSS module来给组件添加样式

注意:使用vite需要将文件名以.module.css结尾。

index.module.css

html, body {
  margin: 0;
  height: 100%;
}
.container {
  position: relative;
  height: 100%;
}
.header {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 60px;
  background: #508bff;
  z-index: 3;
}
.sidebar {
  position: absolute;
  left: 0;
  top: 0;
  padding-top: 80px;
  height: 100%;
  width: 120px;
  z-index: 2;
  background: #f18950;
}
.main {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 70px 10px 10px 130px;
  background: #777;
}

index.jsx

import styles from './index.module.css' 
class Container extends React.Component {
  render() {
    console.log(this.props)
    return (
      <div>
        <div className={styles.header}>
          { this.props.Header }
        </div>
        <div className={styles.sidebar}>
          { this.props.Sidebar }
        </div>
        <div className={styles.main}>
          { this.props.Main }
        </div>
      </div>
    )
  }
}
class Header extends React.Component {
  render() {
    return (
      <p>header</p>
    )
  }
}
class Sidebar extends React.Component {
  render() {
    return (
      <p>sidebar</p>
    )
  }
}
class Main extends React.Component {
  render() {
    return (
      <p>main</p>
    )
  }
}
class App extends React.Component {
  render() {
    return (
      <div>
        <Container Header={ <Header/> } Sidebar={ <Sidebar/> } Main={ <Main/> }>
        </Container>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

为什么JSX可以通过props传递视图元素(React元素)?
1、JSX本质都可以转成React元素(对象Object)
2、视图通过props传递的机制像vue的插槽
3、React中没有slot的这个概念定义
4、React允许通过props传递任何类型的数据到子组件

多层组合

把公共的组件提出来


class Modal extends React.Component {
  render() {
    return (
      <div>
        <header>
          { this.props.headerTit }
        </header>
        <div className='modal-content'>
          { this.props.children }
        </div>
      </div>
    )
  }
}

class Alert extends React.Component {
  render() {
    return (
      <Modal headerTit={this.props.alertTit}>
        <p>{ this.props.alertTxt }</p>
      </Modal>
    )
  }
}

class WelcomeAlert extends React.Component {
  render() {
    return (
      <Alert alertTit="欢迎您, 亲爱的用户" alertTxt="终于等到您!!!"></Alert>
    )
  }
}

class LoginModal extends React.Component {
  render() {
    return (
      <Modal headerTit="登录">
        <form action=''>
          <input type="text" name="" id="" placeholder='用户名' />
          <input type="password" name="" id="" placeholder='密码' />
          <p>
            <button type='submit'>登录</button>
          </p>
        </form>
      </Modal>
    )
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <WelcomeAlert></WelcomeAlert>
        <LoginModal></LoginModal>
      </div>
    )
  }
}


ReactDOM.render(<App />, document.getElementById('app'))

react目前没有发现有需要组件继承的需求
使用上面的传递视图或者传递props就能解决组件组合的问题
组合的方式完全可以替代继承方案

如果是逻辑部分需要继承或者公用
需要自己实现逻辑抽离的模块、函数、类单独进行模块导入使用

1

评论区