组合与继承、CSS Module
props.children
- 如果 Container 标签有内容,React 会在 props 上增加 children 属性
- 如果 Container 标签内部有非元素内容,
children: 就是这个非元素内容
- <Container>123</Container>
- 如果 Container 内部有单个元素内容,
children: React元素对象
<Container><h1>123</h1></Container>
- 如果 Container 内部有多个元素内容,
children:[React元素对象1, React元素对象2,"123",...]
<Container><h1>123</h1><h2>234</h2></Container>
class Container extends React.Component {
render() {
return (
<div className="container">
<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 (
// <Container />
<Container
header={ <Header /> }
sidebar={ <Sidebar /> }
main={ <Main /> }
/>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
props 可以传入 JSX
- 为什么 JSX 还可以通过 props 传递视图元素、React 元素?
- 因为 JSX 本质上都会转成 React 元素(对象 Object)视图通过 props 传递的机制比较像 vue 的插槽
- React 没有 slot 的概念定义
- React 本身就允许通过 Props 传递任何类型的数据到子组件
class Container extends React.Component {
render() {
return (
<div className="container">
<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 (
<Container
header={ <Header /> }
sidebar={ <Sidebar /> }
main={ <Main /> }
/>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
CSS Module
- 前置知识:同一页面引入两个组件,两者皆有
.title
样式,那么后引入的组件的 .title
样式会覆盖前者组件的样式,即样式覆盖
- 此时使用CSS模块化就能避免冲突
- 在 react 脚手架中,内置支持 css module
- 把 CSS 当做模块传入组件内部,用 JS 的逻辑调用样式
- Vite 默认支持的特性, 但文件名有规范:
xxx.module.css
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
h1,
p {
margin: 0;
font-weight: normal;
}
.container {
position: relative;
width: 100%;
height: 100%;
}
.header {
position: absolute;
top: 0;
left: 0;
z-index: 3;
width: 100%;
height: 60px;
background-color: #000;
}
.sidebar {
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 300px;
height: 100%;
padding-top: 80px;
box-sizing: border-box;
background-color: orange;
}
.main {
position: absolute;
box-sizing: border-box;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
padding: 80px 0 0 320px;
background-color: green;
}
import styles from './12.module.css' // 通过模块化方式导入样式
class Container extends React.Component {
render() {
return (
<div className={ styles.container }>
<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 (
<Container
header={ <Header /> }
sidebar={ <Sidebar /> }
main={ <Main /> }
/>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
多层组合