• Web学习笔记-React(组合Components)


    笔记内容转载自 AcWing 的 Web 应用课讲义,课程链接:AcWing Web 应用课

    本节内容是组件与组件之间的组合,例如用不同组件构成 DOM 树,以及给不同的组件传递数据或者调用不同组件的方法,还有不同组件的生命周期。

    1. 创建父组件

    我们还是继续在之前的 Box 组件上进行操作,首先创建一个 Boxes 组件,其中包含一系列 Box 组件。

    components 目录中创建 boxes.jsx

    import React, { Component } from 'react';
    
    class Boxes extends Component {
        state = {  } 
        render() { 
            return (
                <h1>Boxes</h1>
            );
        }
    }
     
    export default Boxes;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    然后修改一下 index.js

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import 'bootstrap/dist/css/bootstrap.css';
    import Boxes from './components/boxes';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(<Boxes />);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    现在我们在 Boxes 中加入多个 Box,当一个组件中包含多个并列元素的时候,需要用一个标签将他们括起来,可以使用 React 中的一个虚拟标签

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        state = {  } 
        render() { 
            return (
                <React.Fragment>
                    <Box />
                    <Box />
                    <Box />
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    为了方便也可以用一个数组来表示,将 Box 的信息存到 state 里,由于 React 组件如果有若干个儿子那么他们的 key 需要不一样,因此还需要存一个唯一的 id

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 0},
                {id: 3, x: 0},
                {id: 4, x: 0},
            ]
         } 
        render() { 
            return (
                <React.Fragment>
                    {this.state.boxes.map(box => (
                        <Box key={box.id} />
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2. 从上往下传递数据

    通过 this.props 属性可以从上到下传递数据。例如我们在 Boxes 中传递 x

    ...
    
    class Boxes extends Component {
        state = { 
            ...
         } 
        render() { 
            return (
                <React.Fragment>
                    {this.state.boxes.map(box => (
                        <Box key={box.id} x={box.x} name='yyj' />
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    可以在 Box 中输出信息 console.log(this.props); 查看内容:

    在这里插入图片描述

    修改 Box 中的 x

    import React, { Component } from 'react';  // 输入imrc即可补全
    
    class Box extends Component {  // 输入cc即可补全
        state = { 
            x: this.props.x,
        };
    
        ...
    }
     
    export default Box;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3. 传递子节点

    可以将标签写成 的形式,然后在标签中添加子标签:

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 0},
                {id: 3, x: 0},
                {id: 4, x: 0},
            ]
         } 
        render() { 
            return (
                <React.Fragment>
                    {this.state.boxes.map(box => (
                        <Box key={box.id} x={box.x} name='yyj'>
                            <h1>Title</h1>
                        </Box>
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 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

    这样 this.props 中会多一个属性 children,可以使用 [] 单独访问某个子标签。我们可以将这个传过来的值定义在任何地方,例如可以放到每个 Box 组件的最上方:

    import React, { Component } from 'react';  // 输入imrc即可补全
    
    class Box extends Component {  // 输入cc即可补全
        state = { 
            x: this.props.x,
        };
    
        handleClickLeft = (step) => {
            this.setState({
                x: this.state.x - step
            });
        }
    
        handleClickRight = (step) => {
            this.setState({
                x: this.state.x + step
            });
        }
    
        handleClickLeftTmp = () => {
            this.handleClickLeft(10);
        }
    
        render() {  // Component类的函数,用来返回当前组件最后渲染的HTML结构是什么
            console.log(this.props);
            return (
            // HTML标签中可以使用{}写一个表达式
            <React.Fragment>
                {this.props.children}
                <div style={this.getStyles()}>{this.state.x}</div>
                <button onClick={this.handleClickLeftTmp} className='btn btn-primary m-2'>Left</button>
                <button onClick={() => this.handleClickRight(10)} className='btn btn-success m-2'>Right</button>
            </React.Fragment>
            );
        }
    
        getStyles() {
            ...
        }
    }
     
    export default Box;
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    4. 从下往上调用函数

    父元素可以通过 this.props 向子元素传递信息,子元素也可以使用函数向父元素传递信息。假设我们需要实现通过点击删除按钮删除某个 Box,其信息保存在 Boxesstate 中,但是我们点击触发事件是在 Box 中(注意:每个组件的 this.state 只能在组件内部修改,不能在其他组件内修改)。

    我们可以在父元素中定义好函数,然后将函数传给子元素:

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 0},
                {id: 3, x: 0},
                {id: 4, x: 0},
            ]
        }
    
        handleDelete = (boxId) => {
            // 遍历一遍state.boxes,将box.id不为传入的参数boxId的数据保留下来
            const res = this.state.boxes.filter(box => box.id !== boxId);
            this.setState({boxes: res});
        }
    
        render() { 
            return (
                <React.Fragment>
                    {this.state.boxes.map(box => (
                        <Box key={box.id} id={box.id} x={box.x} name='yyj'
                            onDelete={this.handleDelete}
                        />
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33

    这样子元素就能调用函数对父元素进行操作了:

    import React, { Component } from 'react';  // 输入imrc即可补全
    
    class Box extends Component {  // 输入cc即可补全
        ...
    
        render() {  // Component类的函数,用来返回当前组件最后渲染的HTML结构是什么
            console.log(this.props);
            return (
            // HTML标签中可以使用{}写一个表达式
            <React.Fragment>
                ...
                <button onClick={() => this.props.onDelete(this.props.id)} className='btn btn-danger m-2'>Delete</button>
            </React.Fragment>
            );
        }
    
        getStyles() {
            ...
        }
    }
     
    export default Box;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    现在我们在 Boxes 中实现一个 Reset 按钮实现清空所有 Boxx

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 1},
                {id: 3, x: 2},
                {id: 4, x: 3},
            ]
        }
    
        handleDelete = (boxId) => {
            ...
        }
    
        handleReset = () => {
            const res = this.state.boxes.map(box => {
                return {
                    id: box.id,
                    x: 0,
                }
            });
            this.setState({boxes: res});
        }
    
        render() {
            console.log(this.state.boxes);
            return (
                <React.Fragment>
                    <button
                        onClick={this.handleReset}
                        style={{marginBottom: '15px'}}
                        className='btn btn-info'
                    >Reset</button>
                    {this.state.boxes.map(box => (
                        <Box key={box.id} id={box.id} x={box.x} name='yyj'
                            onDelete={this.handleDelete}
                        />
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    在控制台观察时可以发现点击 Reset 按钮后 x 确实置零了,但是 Box 显示出来的 x 并没有改变,这是因为 state 值不能在外部修改,因此我们可以将 Box 中的 state 删掉,需要在该组件中渲染外面的 state 的值。

    每个维护的数据仅能保存在一个 this.state 中,不要直接修改 this.state 的值,因为 setState 函数可能会将修改覆盖掉。

    修改 Boxes,将之前 Box 中操作 state 的函数转移过来:

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 1},
                {id: 3, x: 2},
                {id: 4, x: 3},
            ]
        }
    
        handleDelete = (boxId) => {
            // 遍历一遍state.boxes,将box.id不为传入的参数boxId的数据保留下来
            const res = this.state.boxes.filter(box => box.id !== boxId);
            this.setState({boxes: res});
        }
    
        handleReset = () => {
            const res = this.state.boxes.map(box => {
                return {
                    id: box.id,
                    x: 0,
                }
            });
            this.setState({boxes: res});
        }
    
        // 需要知道修改的是哪个box
        handleClickLeft = (box) => {
            const boxes = [...this.state.boxes];  // 浅拷贝一份
            const k = boxes.indexOf(box);  // 传入的box是引用,找出其在boxes中的下标k
            boxes[k] = {...boxes[k]};  // 再clone一遍,相当于创建新的state,深拷贝
            boxes[k].x--;
            this.setState({boxes: boxes});
        }
    
        handleClickRight = (box) => {
            const boxes = [...this.state.boxes];
            const k = boxes.indexOf(box);
            boxes[k] = {...boxes[k]};
            boxes[k].x++;
            this.setState({boxes: boxes});
        }
    
        render() {
            return (
                <React.Fragment>
                    <button
                        onClick={this.handleReset}
                        style={{marginBottom: '15px'}}
                        className='btn btn-info'
                    >Reset</button>
    
                    {this.state.boxes.map(box => (
                        <Box key={box.id} id={box.id} x={box.x} name='yyj'
                            onDelete={this.handleDelete}
                            onClickLeft={() => this.handleClickLeft(box)}
                            onClickRight={() => this.handleClickRight(box)}
                        />
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    然后修改 Box,将 this.state 替换成父组件传递过来的 props

    import React, { Component } from 'react';  // 输入imrc即可补全
    
    class Box extends Component {  // 输入cc即可补全
        render() {  // Component类的函数,用来返回当前组件最后渲染的HTML结构是什么
            return (
            // HTML标签中可以使用{}写一个表达式
            <React.Fragment>
                <div style={this.getStyles()}>{this.props.x}</div>
                <button onClick={this.props.onClickLeft} className='btn btn-primary m-2'>Left</button>
                <button onClick={this.props.onClickRight} className='btn btn-success m-2'>Right</button>
                <button onClick={() => this.props.onDelete(this.props.id)} className='btn btn-danger m-2'>Delete</button>
            </React.Fragment>
            );
        }
    
        getStyles() {
            let styles = {
                width: '50px',
                height: '50px',
                backgroundColor: 'lightblue',
                color: 'white',
                textAlign: 'center',
                lineHeight: '50px',
                borderRadius: '5px',
                position: 'relative',
                left: this.props.x
            };
    
            if (this.props.x === 0) {
                styles.backgroundColor = 'orange';
            }
    
            return styles;
        }
    }
     
    export default Box;
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    5. 兄弟组件间传递消息

    如果组件的结构关系更为复杂,那么就需要将多个组件共用的数据存放到最近公共祖先this.state 中。

    我们创建一个 App 组件,其包含两个子组件 NavBar(导航栏)和 Boxes,这两个组件为兄弟组件。

    首先是 navbar.jsx

    import React, { Component } from 'react';
    
    class NavBar extends Component {
        state = {  } 
        render() { 
            return (
                <nav className="navbar bg-body-tertiary">
                    <div className="container-fluid">
                        <a className="navbar-brand" href="/">Navbar</a>
                    </div>
                </nav>
            );
        }
    }
     
    export default NavBar;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    然后是 app.jsx

    import React, { Component } from 'react';
    import NavBar from './navbar';
    import Boxes from './boxes';
    
    class App extends Component {
        state = {  } 
        render() { 
            return (
                <React.Fragment>
                    <div className='container'>
                        <NavBar />
                        <Boxes />
                    </div>
                </React.Fragment>
            );
        }
    }
     
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    现在假设我们要在 NavBar 中存放 Boxes 中有几个 Box 的信息,那么只能把信息放到这两个组件的最近公共祖先 App 中。

    我们将 Boxes 中与 state 有关的内容都移到 App 中:

    import React, { Component } from 'react';
    import Box from './box';
    
    class Boxes extends Component {
        render() {
            return (
                <React.Fragment>
                    <button
                        onClick={this.props.onReset}
                        style={{marginBottom: '15px'}}
                        className='btn btn-info'
                    >Reset</button>
    
                    {this.props.boxes.map(box => (
                        <Box key={box.id} id={box.id} x={box.x} name='yyj'
                            onDelete={this.props.onDelete}
                            onClickLeft={() => this.props.onClickLeft(box)}
                            onClickRight={() => this.props.onClickRight(box)}
                        />
                    ))}
                </React.Fragment>
            );
        }
    }
     
    export default Boxes;
    
    • 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

    移动后的 App 如下:

    import React, { Component } from 'react';
    import NavBar from './navbar';
    import Boxes from './boxes';
    
    class App extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 1},
                {id: 3, x: 2},
                {id: 4, x: 3},
            ]
        }
    
        handleDelete = (boxId) => {
            // 遍历一遍state.boxes,将box.id不为传入的参数boxId的数据保留下来
            const res = this.state.boxes.filter(box => box.id !== boxId);
            this.setState({boxes: res});
        }
    
        handleReset = () => {
            const res = this.state.boxes.map(box => {
                return {
                    id: box.id,
                    x: 0,
                }
            });
            this.setState({boxes: res});
        }
    
        // 需要知道修改的是哪个box
        handleClickLeft = (box) => {
            const boxes = [...this.state.boxes];  // 浅拷贝一份
            const k = boxes.indexOf(box);  // 传入的box是引用,找出其在boxes中的下标k
            boxes[k] = {...boxes[k]};  // 再clone一遍,相当于创建新的state,深拷贝
            boxes[k].x--;
            this.setState({boxes: boxes});
        }
    
        handleClickRight = (box) => {
            const boxes = [...this.state.boxes];
            const k = boxes.indexOf(box);
            boxes[k] = {...boxes[k]};
            boxes[k].x++;
            this.setState({boxes: boxes});
        }
    
        render() { 
            return (
                <React.Fragment>
                    <div className='container'>
                        <NavBar
                            boxesCount={this.state.boxes.length}  // 将长度传给NavBar
                        />
                        <Boxes
                            boxes={this.state.boxes}
                            onReset={this.handleReset}
                            onClickLeft={this.handleClickLeft}
                            onClickRight={this.handleClickRight}
                            onDelete={this.handleDelete}
                        />
                    </div>
                </React.Fragment>
            );
        }
    }
     
    export default App;
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    现在即可在 NavBar 中读取 Boxes 的长度信息了:

    import React, { Component } from 'react';
    
    class NavBar extends Component {
        state = {  } 
        render() { 
            return (
                <nav className="navbar bg-body-tertiary">
                    <div className="container-fluid">
                        <a className="navbar-brand" href="/">
                            Navbar <span>Boxes Count: {this.props.boxesCount}</span>
                        </a>
                    </div>
                </nav>
            );
        }
    }
     
    export default NavBar;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6. 无状态函数组件

    当组件中没有用到 this.state 时,可以简写为无状态的函数组件。类相对于函数最大的好处就是可以很方便地维护状态(局部变量)。

    无状态函数组件(Stateless Funtion Component),输入 sfc 即可自动补全出来。函数组件相当于只有 render 函数的类组件。注意:函数的传入参数为 props 对象:

    import React from 'react';
    
    const NavBar = (props) => {
        return (
            <nav className="navbar bg-body-tertiary">
                <div className="container-fluid">
                    <a className="navbar-brand" href="/">
                        Navbar <span>Boxes Count: {props.boxesCount}</span>
                    </a>
                </div>
            </nav>
        );
    }
     
    export default NavBar;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    7. 组件的生命周期

    • Mount 周期(挂载,表示对象被创建出来),执行顺序(按顺序执行三个函数):constructor() -> render() -> componentDidMount()
    • Update 周期(修改,例如点击按钮),执行顺序:render() -> componentDidUpdate()
    • Unmount 周期(删除),执行顺序:componentWillUnmount()

    其中,componentDidUpdate 函数有两个参数,分别表示更新前的 propsstate

    import React, { Component } from 'react';
    import NavBar from './navbar';
    import Boxes from './boxes';
    
    class App extends Component {
        state = { 
            boxes: [
                {id: 1, x: 0},
                {id: 2, x: 1},
                {id: 3, x: 2},
                {id: 4, x: 3},
            ]
        }
    
        componentDidUpdate(prevProps, prevState) {
            console.log('App - Update');
            console.log(prevProps, this.props);
            console.log(prevState, this.state);
        }
    
        ...
    
        render() {
            console.log('App - Render');
            return (
                ...
            );
        }
    }
     
    export default App;
    
    • 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
    • 29
    • 30
    • 31

    输出的 state 内容如下:

    {boxes: Array(4)}
    	boxes: Array(4)
    		0: {id: 1, x: 0}
    		1: {id: 2, x: 1}
    		2: {id: 3, x: 2}
    		3: {id: 4, x: 3}
    		length: 4
    		[[Prototype]]: Array(0)
    	[[Prototype]]: Object
    
    {boxes: Array(4)}
    	boxes: Array(4)
    		0: {id: 1, x: 1}  (此处有区别)
    		1: {id: 2, x: 1}
    		2: {id: 3, x: 2}
    		3: {id: 4, x: 3}
    		length: 4
    		[[Prototype]]: Array(0)
    	[[Prototype]]: Object
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    【frp】cron定时检查zfrpc.service是否启动成功
    Oracle归档日志暴增排查优化
    平面曲线与曲面
    C++多线程学习02 线程的入口参数
    Packet Tracer模拟一次简单的HTTP请求
    “AmyTrack“app Tech Support(URL)
    java ssm+python儿童疫苗接种提醒系统e6lhv
    python获取ajax加载的数据
    【Java八股文总结】之JDK8新特性
    ElasticSearch实现分词模糊查询
  • 原文地址:https://blog.csdn.net/m0_51755720/article/details/132780159