组件化开发与路由配置

4/27/2024 react

# 组件化开发与路由配置

  • 父子组件传值

    • 父传子 【单向数据流】
    • 子传父
  • 插槽

    • 匿名插槽
    • 具名插槽
  • react-router

    • 配置式
    • 约定式

# 1.插槽

插槽传第的数据 是 一段 html代码

默认情况下,插槽都是空的

父组件通过 在调用子组件的两个标签之间 <Son> <html代码> </Son>

子组件 通过 props.children 接收 父组件传递的所有的 html代码

​ 1.父组件如果没有传递 插槽代码 props.children ===undefined

2.父组件如果传递了 一行html插槽的代码 props.children === 这行html代码对应的 虚拟dom对象

3.父组件如果传了 多行html插槽代码, props.children === [多个虚拟dom对象 组成的 数组]

子组件显示插槽代码 ,直接使用 {虚拟dom对象} 达到渲染的效果 {props.children}

  • 父组件
import React from "react";
import Son from "./Son";
export default function Father() {
  return (
    <div>
      <h1> 我是父组件的代码 </h1>
      {/* undefined ==[]*/}
      <Son></Son>

      {/* {}  == [{}]*/}
      <Son>
        <div>啦啦啦啦</div>
      </Son>
      {/* [{},{}] */}
      <Son>
        <p id="10000">我是爸爸传递的 插槽,需要子组件显示</p>
        <h2>我是爸爸组件传递的另一个插槽也需要显示</h2>
      </Son>
    </div>
  );
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • 子组件
import React from 'react'

export default function Son(props) {
    console.log('子组件接收的参数');
    console.log(props.children); 
    // 如果父组件传递了一句html代码 props.children 就可以直接渲染了
    let children = props.children
    if(!props.children){
        children = []
    }
    if(props.children && !Array.isArray(props.children) ){
        children = [props.children]
    }
  return (
    <div>
        <div>我是儿子组件</div>
        <div className="box">
            我正在处理 xxx业务
        </div>
        <div className="msg">
           {children.map(item=>item)}
        </div>
        <hr />
    </div>
  )
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 2.插槽 props.children 处理

如果需要判断 插槽 传递的 具体值 最后转换为 数组 再进行显示 可以通过 React.Children.toArray(props.children)`

如果没有传递 插槽 ====> []

如果传递了一个html ====>[{}]

如果传递了 多个 html ====>[{},{}]

import React from 'react'

export default function Son(props) {
 	let children = React.Children.toArray(props.children)
  return (
    <div>
        <div>我是儿子组件</div>
        <div className="box">
            我正在处理 xxx业务
        </div>
        <div className="msg">
           {children.map(item=>item)}
        </div>
        <hr />
    </div>
  )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3.具名插槽

有名字的插槽

  • 父组件

父组件 调用子组件 传递插槽代码 可以在代码 属性上 加 slot=xxxx

   <Title>
        <div className="menu" slot="center">
          <div className="item">华语</div>
          <div className="item">流行</div>
          <div className="item">华语</div>
          <div className="item">流行</div>
          <div className="item">华语</div>
          <div className="item">流行</div>
        </div>
        <div>更多</div>

        <div slot="title">热门推荐</div>
      </Title>
      <Title>
        <div>更多</div>
        <div slot="title">新碟上架</div>
      </Title>
      <Title>
        <div slot="title">
          全部
          <select name="" id="">
            <option value="选择分类"></option>
            <option value="国风歌曲"></option>
          </select>
        </div>
        <button>热门</button>
      </Title>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  • 子组件

可以通过 slot 属性 区分不同的插槽 并获取出来 放到各自的位置

import React from 'react'
import './title.css'
export default function Title(props) {
    let children = React.Children.toArray(props.children)
    console.log(children);
    //根据 slot名字 过滤删选出 对应的 名字的插槽
    let titleSlots = children.filter(item=>item.props.slot =='title')
    let centerSlots = children.filter(item=>item.props.slot =='center')
    let defaultSlots = children.filter(item=>item.props.slot==undefined)

  return (
    <div className='title'>
        <div className="left">  
         {titleSlots.map(item=>item)}
        </div>
        <div className="list">
            {centerSlots.map(item=>item)}
        </div>
        <div className="btn">
            {defaultSlots.map(item=>item)}
        </div>
    </div>
  )
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 4.路由

# 1.路由使用

  • 安装react-router-dom
yarn add react-router-dom

npm i react-router
1
2
3

2.配置路由

# 5.预处理css

# 6.其他hooks