当前位置:首页 > 程序设计 > 正文内容

React基础学习

雨源1个月前 (03-28)程序设计16


React中文官网文档学习


react脚手架的安装

在安装react脚手架之前,要确保本地电脑中,已经安装过来nodejs的环境。

安装官方脚手架

 npm i -g create-react-app

初始化

 create-react-app 项目名称


扩展

在执行初始化命令的时候,会发现终端中会下载 react,react-dom,react-scripts三个包。

react包就是处理react项目的逻辑,react-dom包将虚拟dom渲染成真实dom,react-scripts包是react的脚本包,包含了许多编写react时所需要的各种包和配置环境。

如果碰到安装太慢,就先停止初始化,然后执行以下命令:

npm config set registry http://registry.npmmirror.com 然后再重新初始化。


然后依次执行以下命令(终端中也会提示)

 # 第一步:进入到react项目目录中
 cd 项目名称

执行完命令,在工程目录下会生成以下目录结构

 -项目名称
  -node_modules # 项目包依赖的文件
  -public # 静态资源
  -src # 源码,在开发过程中最常用的文件
  -.gitignore
  -package.json # 配置文件
  -README.md
  -yarn.lock # 入口文件
 # 第二步:启动项目
 npm start

由于刚上手react框架,刚生成的项目目录中含有许多陌生的文件,但是前期的基础学习用不到这些文件,所以建议将src目录中的以下文件删除,让整个项目更干净,更有利于学习react。

 # src目录下要删除的文件
 App.css
 App.js
 App.test.js
 index.css
 index.js
 serviceWorker.js

然后在src目录下新建一个index.js的空文件,然后往index.js文件中写入以下内容,作为项目的入口文件。

 // 项目的入口文件
 import React from "react";
 import ReactDOM from "react-dom";
 
 ReactDOM.render(<div>Hello World!</div>, document.getElementById("root"));

然后在浏览器中打开http://localhost:3000 地址,看到 Hello World! 的字样,则说明项目搭建成功。


JSX介绍

jsx 等价于 javaScript + Xml,jsx就是一个对象,被称之为虚拟DOM元素。

 <h2>hello,react<h2>
 这个就是一个jsx对象,也就是虚拟DOM对象


import React from "react";
import ReactDOM from "react-dom";

// 此时,这个 <h2>hello,react<h2> 就是一个jsx对象
const ele = <h2>hello,react<h2>;
console.log(ele);
// 将ele处插入到id为root的标签中
ReactDOM.render(ele,document.querySelector('#root'));

模板语法渲染

插入动态的元素

// 使用{}就可以插入动态的元素,这个元素可以是任意内容
const ele = <h2>hello,{'react'}<h2>;

将函数插入到ReactDOM.render()中

import React from "react";
import ReactDOM from "react-dom";

function getGeeting(user){
    if(user){
        return <h1>hello,{user}</h1>;
    }
    return <h1>hello,react</h1>;
}

// 这里如果直接插入jsx对象,必须要用div标签包裹
ReactDOM.render(<div>getGeeting('用户名')</div>,document.querySelector('#root'));

元素渲染

元素是构成React应用的最小砖块,比如:

const ele = <h1>hello,world</h1>

与浏览器的DOM元素不同,React元素创建开销极小的普通对象,React DOM会负责更新DOM来与React元素保持一致。

ReactDOM.render() 其实就是在渲染DOM节点。

也就是说,react只更新它需要更新的部分。

案例

下面这段代码案例,实现的效果就是时间在变化,也就是,在整个页面中,只有h2元素在变动,其他元素都没有做任何改变。

import React from "react";
import ReactDOM from "react-dom";

function tick() {
    const element = (
        <div>
             <h1>Hello, world!</h1>
             <h2>{new Date().toLocaleTimeString()}.</h2>
 </div>
     );
    ReactDOM.render(element, document.querySelector('#root'));
}
setInterval(tick, 1000);


循环语句

循环语句,可以用 map((item,index)=>{})

import React from "react";
import ReactDOM from "react-dom";

const arr = ['1','2','3']

const ulEle = (
    <ul>
     {arr.map((item,index)=>{
    // 循环绑定的jsx元素,必须要有key属性,来区分不同的元素,否则会报错
     return <li key={item}>{item}</li>
 })}
    </ul>
)

ReactDOM.render(elEle,document.querySelector('#root'));

过滤语句

import React from "react";
import ReactDOM from "react-dom";

const goods = [
    {id:1.price:100,title:'小米6手机'},
    {id:2.price:200,title:'小米7手机'},
    {id:3.price:1100,title:'小米8手机'},
    {id:4.price:2000,title:'小米9手机'},
]

// 过滤操作:取出goods中price大于1000的数据
// 使用三元运算符来实现过滤效果
const filterEle = (
    <ul>
        {
            goods.map((good,index)=>{
                // 使用三目运算符 实现 过滤功能
                return (good.price >1000 ? <li key={good.id}>{good.title}</li> : null)
            })
        }
    </ul>
)


ReactDOM.render(filterEle,document.querySelector('#root'));


组件的创建

react核心的思想就是组件化开发,其实就是玩JavaScript。

react有两种创建组件的方式,一种是函数声明,一个是类声明。


函数声明

import React from "react";
import ReactDOM from "react-dom";

// 第一步:用函数定义组件
// function 组件名(){}
// 注意:组件名的首字母必须要大写,否则报错
function Weclome(props){
    // (固定)props 接受 name='Welcome'
    // 如果组件没有传值,props就为空
    return <h2>hello,{props.name}</h2>
}


// 第二步:使用组件 <组件名 />
ReactDOM.render(<Welcome name='Welcome' />,document.querySelector('#root'));



类声明

类声明的组件,使用的更多,类声明的组件声明周期。

注意:

1.React.Component是一个基类,使用类声明的组件,必须继承整个基类。

2.在类中,必须有render函数。

3.在render函数中,需要return 一个 jsx 元素。

4.组件的名称要以大写字母开头


// 必须继承React.Componet
class App extends React.Component{
    // 必须使用render()函数 能将虚拟DOM渲染成真实DOM
    render(){
        // 获取组件中传来的值: this.props.值
        // 它会将jsx所接收的属性转换为单个对象传递到组件,整个对象我们称为为props
        return <h2>App,{this.props.name}</h2>
    }
}

ReactDOM.render(<App name="你好" />,document.querySelector('#root'));

当然了,函数式组件的声明,也可以放在外部文件单独声明,然后到导入到index.js中。

比如,在src目录下,新建一个App.js文件,往里面写入以下代码(将上面的代码复制过来就好)

// App.js文件
import React,{Component} from 'react';
export default class App extends Component{
    render(){
        return <h2>App,{this.props.name}</h2>
    }
}

ReactDOM.render(<App name="你好" />,document.querySelector('#root'));

然后再回到index.js文件中,引入App.js组件

import React from 'react';
import ReactDOM from 'react-dom';
// 引入 App.js文件
import App from './App';
ReactDOM.render(<App name="你好" />,document.querySelector('#root'));


扩展

在使用vscode编辑器的时候,会发现定义一个类声明的组件,写法很麻烦,这里推荐一个vscode的插件,叫 ES7+ React/Redux/React-Native snippets ,只需要在代码中,写rcc就可以自动生成以下代码

import React,{Component} from "react";

// 这里的App 取决于文件名
export default class App extends Component {
  render() {
    return (
      <div>App</div>
    )
  }
}

可以说是非常方便。

组件的复用

1.组件的复用可以将多个组件进行整合,例如调用多次相同的组件。

2.结构非常复杂时需要将组件拆分成小组件

3.会存在父子关系的数据传递


// App.js文件
import React,{Component} from "react";

class MyBtn extends Component{
    render(){
        return (
         <button>{this.props.title}</button>
        )
    }
}

export default class App extends Component{
    render(){
        return(
             <div>
                <h2>hello</h2>
                // 调用MyBtn类组件 复用组件
                <MyBtn> title="提交"</MyBtn>
                <MyBtn> title="删除"</MyBtn>
            </div>
        )
    }
}

组件的拆分

将一个组件细分成更多的小组件。

扩展

在html中类名是class,但是在react中类名是className

// App.js文件

import React,{Component} from "react";

// 按钮组件
class MyBtn extends Component{
    render(){
        return (
         <button>{this.props.title}</button>
        )
    }
}

// 评论中 用户信息 中 头像组件
class Avatar extends Component{
    render(){
        return(
            <img src={this.props.avatarUrl} alt="" />
        )
    }
}


// 评论中 用户信息组件
class UserInfo extends Component{
    render(){
        return(
            <div className='userinfo'>
             <Avatar avatarUrl={this.props.avatarUrl}></Avatar>
     <div className="username">
     {this.props.name}
     </div>
            </div>
        )
    }
}





// 评论组件
class Comment extends Component{
    render(){
        return(
             //在html中类名是class,但是在react中类名是className
                <div className='comment'>
             {/*用户信息*/}
     <UserInfo {...this.props.user}></UserInfo>
     {/*用户评论内容*/}
 <div className='comment-content'>
                      评论内容:{this.props.user.content}
                    </div>
 {/*用户评论时间*/}
 <div className='comment-date'>
                      发布时间:{this.props.user.date}
                    </div>
                </div>
        )
    }
}


// App 主组件
export default class App extends Component{
    constructor(props){
        super(props);
        // 遵循单向数据流
        // 模拟后端传数据
        this.user = {
            avatarUrl:'https://img2.baidu.com/it/u=1316245042,2395535024&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
            name:'用户',
            content:'这是我的react组件',
            date:new Date().toLocaleTimeString()
        }
    }
    
    render(){
        return(
             // 调用MyBtn类组件 复用组件
            <div>
                <h2>hello</h2>
                <MyBtn title="提交"></MyBtn>
                <MyBtn title="删除"></MyBtn>
                <MyBtn title="修改"></MyBtn>
                <MyBtn title="添加"></MyBtn>
             <Comment user={this.user}></Comment>
        </div>
        )
    }
}


css样式

想要给组件设置样式,就要在src目录下单独再创建一个css文件,然后再组件中导入该样式文件。

/* App.css */
/* App.js */
import './App.css'


子组件向父组件传递数据

子组件想要向父组件传递数据,就要在子组件和父组件中分别定制一个方法,在方法中来实现数据的传递。

import React,{Component} from "react";

// 子组件
class Child extends Component{
    handleClick = () => {
        // 调用父组件传递过来的方法
        // 将值通过props传递给父组件
        this.props.add('子组件中的值');
    }

    render(){
        return(
            <div>
                <div>Child</div>
                <button onClick={this.handleClick}>子传父</button>
            </div>
        )
    }
}


// 父组件
export default class Demo extends Component{
    
    add(val){
        // 获取子组件传递来的值
        alert(val)
        console.log(val)
    }

    render(){
        return (
            <div>
                <h2>Parent</h2>
                <hr/>
                <Child add={this.add}></Child>
            </div>
        )
    }
}

注意:组件之间,想要修改值,不能直接修改。


State状态

State属性

组件内部以及组件之间的数据,不能直接的修改,要通过用State的方式定义数据和修改数据。

/* App.js */
import React, { Component } from 'react'

export default class App extends Component {
    constructor(props){
        super(props);
        // 1.在 constructor函数种使用this.state来定义数据
        this.state = {
            count:0
        }
    }
    add =()=>{
        // 2.修改状态的唯一方法是调用this.setState()
        this.setState({
            count:this.state.count+1
        })
    }
  render() {
    console.log("渲染了")
    return (
      <div>
            <h2>{this.state.count}</h2>
            <button onClick={this.add}>+1</button>
            
      </div>
    )
  }
}

State状态的this指向

在React中,用State修饰数据,要注意this指向的问题。如果处理不好this指向的问题,那就会得不到数据,也就修改不了数据。

修改this指向的方法

第一种方式

在 constructor方法中,将this绑定给add方法

// 在 constructor方法中
constructor(props){
        super(props);
        this.state = {
            count:0
        }
        // 第一种方式:改变this的指向
        this.add = this.add.bind(this)
    }

add(){
        // 除了constructor之外的其他地方,修改状态的唯一方法是调用this.setState()
        this.setState({
            count:this.state.count+1
        })
    }
  render() {
    console.log("渲染了")
    return (
      <div>
            <h2>{this.state.count}</h2>
            <button onClick={this.add}>+1</button>
            
      </div>
    )
  }

第二种方式

给修改数据的方法(add) 使用箭头函数

// 在 constructor方法中
constructor(props){
        super(props);
        this.state = {
            count:0
        }
    }

add = () => {
        // 除了constructor之外的其他地方,修改状态的唯一方法是调用this.setState()
        this.setState({
            count:this.state.count+1
        })
    }
  render() {
    console.log("渲染了")
    return (
      <div>
            <h2>{this.state.count}</h2>
            <button onClick={this.add}>+1</button>
            
      </div>
    )
  }

第三种方式

在标签中使用bind方式绑定

<button onClick={this.add.bind(this)}>+1</button>

第四种方式

推荐使用,因为传值方便

在标签中,使用箭头函数

add(e){}
render() {
 return(
 <button onClick={(e)=>this.add(e)}>+1</button>
 )
}

完整代码

import React, { Component } from 'react'

export default class App extends Component {
    constructor(props){
        super(props);
        this.state = {
            count:0
        }
        // 第一种方式:改变this的指向
        this.add = this.add.bind(this)
    }
    // 第三种方式:使用箭头函数
    add =()=>{
        // 除了constructor之外的其他地方,修改状态的唯一方法是调用this.setState()
        
        this.setState({
            count:this.state.count+1
        })
    }
  render() {
    console.log("渲染了")
    return (
        // 第二种方式改变this指向
        // <button onClick={this.add.bind(this)}>+1</button>


        // 第四种方式:
        // 推荐使用,因为传值方便
        // <button onClick={()=>this.add()}>+1</button>

      <div>
            <h2>{this.state.count}</h2>
            <button onClick={this.add}>+1</button>
            
      </div>
    )
  }
}

setState方法的使用

上面用的setState({}) 对象形式 会有一个弊端,这个弊端是因为react内部是异步执行代码,所以这个弊端就会造成一个现象:

constructor(props){
        super(props);
        this.state = {
            count:0
        }
    }

add = () => {
        this.setState({
            // 此时count已经+1,所以当第一次点击的时候,count的结果是2
            count:this.state.count+1
        })
    // 虽然count的结果已经改成2了,但是这里打印出的结果仍然是1
    //这就是异步造成的结果,上面代码和下面代码同时进行,同时修改值,同时输出打印,所以值是修改了,但是打印的还是修改前的值
     console.log(this.state.count)
    
    }

所以为了解决上述的弊端问题,下面就引入了

// prevState 表示之前的状态
// prevProps 表示之前的属性
this.setState((prevState,prevProps)=>({
    // 修改值的操作
}),()=>{
    // 处理最新的状态
})

函数方式,来解决。

代码案例

// 在 constructor方法中
constructor(props){
        super(props);
        this.state = {
            count:0
        }
    }

add = () => {
     // 使用setState()函数
     this.setState((prevState,prevProps)=>({
            // 修改count的值
            count:prevState.count + 1
        }),()=>{
            // 处理最新的状态
            console.log(this.state.count);
        })
     
    }

其实,针对于这个计数器的案例来说,如果直接使用this.setState({}) 对象的形式来修改count值,也可以用 count:this.state.count+=1 的形式来实现页面显示的数据 和 打印输出 的数据相同。


React生命周期



案例

在src目录下新建一个LifyCycle.js文件

// LifyCycle.js

import React,{ Component } from 'react'

// 子组件
export class SubCount extends Component{
    componentWillReceiveProps(newProps){
        console.log('子组件将要接收新属性',newProps);
    }
    render(){
        return(
            <div>
             
            </div>
        )
    }
}



export default class LifeCycle extends Component{
    static defaultProps = {
        // 1.加载默认的属性
        name:'小马哥',
        age:18
    }
    constructor(props){
        super(props);
        console.log('1.初始化 加载默认的状态');
        this.state = {
            count:0
        }
    }
    
    componentWillMount(){
        console.log('2.父组件将要被挂载');
    }
    
    componentDidMount(){
        // 在当前的这个方法中,发起ajax请求,获取数据,数据驱动视图
        console.log('4.父组件挂载完成');
    }
    
    shouldComponentUpdate(nextProps,nextState){
        // 性能的优化点 重要
        // 绝对组件是否要重新渲染
        console.log('5.组件是否要更新');
        if(nextState.count % 2 === 0){
            return false;
        }else{
            return true;
        } 
    }
      
    componentWillUpdate(){
        console.log('7.组件将要更新');
    }

    componentDidUpdate(){
        console.log('8.组件已经更新完成');
    }
    
    componentWillUnmount(){
        console.log('组件卸载完成');
    }
    
    
    handleClick=() => {
        this.setState((preveState,preveProps)=>({
            count:preveState.count + 1
        }),()=>{
            console.log(this.state.count);
        })
    }
    
    render(){
        console.log('3.父组件(render)了');
        return (
         <div>
             <h2>当前的值:{this.state.count}</h2>
 <button onClick={this.handleClick}>+1</button>
                <SubCount count={this.state.count}></SubCount>
            </div>
        )
    }
}


受控组件

受控组件就是 受状态控制的组件,需要与状态进行相应的绑定

受控组件必须要有一个onChange事件,否则不能使用

受控组件可以赋予默认值(实际上就是设置初始状态)

案例

新建一个ControlInput.js文件做案例

// ControlInput.js
import React, { Component } from 'react'

export default class ControlInput extends Component {
    constructor(props){
        super(props);
        this.state = {
            val:'', // 设置初始值
            data:[]
        }
    }

    handleChange = (e) => {
        // 获取input输入框的值
        let val = e.target.value;
        this.setState({
            val
        })
        // 打印input中的值
        console.log(this.state.val);

    }


    // 按钮点击事件
    handleClick = () => {
        if(this.state.val){
            let newArr = [...this.state.data];
            newArr.push(this.state.val);
            this.setState({
                data:newArr
            })
            // 添加完毕,清空输入框
            this.setState({
                val:''
            })
        }
    }
  render() {
    return (
      <div>
        <input type="text" value={this.state.val} onChange={this.handleChange}/>
        <button onClick={this.handleClick}>添加数据</button>
        <ul>
            {
                this.state.data && this.state.data.map((item,i)=>{
                    return (
                        <li key={i}>{item}</li>
                    )
                })
            }
        </ul>
      </div>
    )
  }
}

记住在index.js中导入并且使用该文件

// index.js
import ControlInput from "./ControlInput";

// 加载组件
ReactDOM.render(<ControlInput/>,document.querySelector('#root'));


非受控组件

非受控组件就是不受状态的控制,有点类似于vue中的双向数据绑定

实现过程

1.通过ref标记一个元素,然后可以通过this.refs.xxx 来获取这个元素

2.通过onChange事件监听到value的变化,获取到这个数据

3.然后通过操作DOM将数据放到需要的地方

案例

新建一个NoControlInput.js文件做案例

// NoControlInput.js
import React,{Component} from "react";

// 非受控组件
export default class NoControlInput extends Component{
    constructor(props){
        super(props);
        this.state = {
            val:'' // 设置input的初始值为空
        }s
    }

    // 当input组件发生变化时,触发
    handleChange = (e) => {
        // 通过refs.xxx.value 获取input的值
        let val = this.refs.a.value;
        this.setState({
            val
        })
    }
    render(){
        return(
            <div>
                <input type="text" onChange={this.handleChange} ref="a" />
                <h2>{this.state.val}</h2>
            </div>
        )
    }
}

记住在index.js中导入并且使用该文件

// index.js
import NoControlInput from "./NoControlInput";

// 加载组件
ReactDOM.render(<NoControlInput/>,document.querySelector('#root'));



表单的使用

案例

新建一个FormSimple.js文件做案例

import React,{Component} from "react";

export default class FormSimple extends Component{
    constructor(props){
        super(props);
        this.state = {
            usename:'',
            password:'',
            selectedArr:[]
        }
    }

    handleUserName = (e) => {
        this.setState({
            username:e.target.value
        })
    }

    handlePassword = (e) => {
        this.setState({
            password:e.target.value
        })
    }

    handleSelectedChange = (e) => {
        let newArr = [...this.state.selectedArr];
        // 将选中的数据添加到数组中
        newArr.push(e.target.value);
        this.setState({
            selectedArr:newArr
        })
    }

    // 表单一旦提交,就触发该方法
    handleSubmit = (e)=> {
        // 阻止默认事件
        e.preventDefault();
        if(this.state.username && this.state.password && this.state.selectedArr && this.state.selectedArr.length>0){
            let arr = this.state.selectedArr.map(n=>(`${n}`))
            // 模拟 发送ajax请求
            alert(`当前用户名:${this.state.username},密码:${this.state.password},我的爱好:${arr}`)
        }
    }

    
    render(){
        return(
            <form onSubmit={this.handleSubmit}>
                <p className="username">
                    <label htmlFor="name">用户名:</label>
                    <input type="text" value={this.state.username} onChange={this.handleUserName} id="name" />
                </p>
                <p className="password">
                    <label htmlFor="pwd">密码:</label>
                    <input type="text" value={this.state.password} onChange={this.handlePassword} id="pwd" />
                </p>
                我的爱好
                <select multiple value={this.state.selectedArr} onChange={this.handleSelectedChange}>
                    <option value="smoking">抽烟</option>
                    <option value="tangtou">烫头</option>
                    <option value="drink">喝酒</option>
                </select>
                <br/>
                <input type="submit" value="登录"/>
            </form>
        )
    }  
}

扩展

在html中,label标签使用的是for属性,但是在react中,使用的是htmlFor属性


记住在index.js中导入并且使用该文件

// index.js
import FormSimple from './FormSimple';

// 加载组件
ReactDOM.render(<FormSimple />,document.querySelector('#root'));


React组件化

前期准备

首先新建一个react组件化文件夹,然后创建 02_component 的react工程项目。

create-react-app 02_component # 创建react工程

yarn安装

npm install -g yarn


Ant-Design的使用

Anr-Design-of-React的文档地址

Ant-Design的环境依赖安装

在终端中,进入到项目的目录当中,下载依赖包

cnpm i antd -S
# 或者
yarn add antd

注意:cnpm要在安装了淘宝镜像源才能使用。

yarn要安装了之后才能使用。


全局导入组件(不推荐)

在App.js文件中导入ant-design

// import 组件 from 'antd/es/组件'
// 比如说导入button
import Button from 'antd/es/button';
import 'antd/dist/reset.css';

使用Button组件

function App(){
    return (
     <div>
         <Button type="primary">登录<Button>
        </div>
    )
}

由于全局导入的方式太过于消耗内存资源,所以建议使用高级配置。

按需导入组件(推荐)

安装依赖

cnpm i react-app-rewired customize-cra babel-plugin-import

修改配置文件

1.修改package.json文件

// 将"scripts"对象中的 react-scripts全部改为react-app-rewired

// 大概在14至18行

2.在项目的根目录下新建一个config-overrides.js 文件,必须叫这个名字。

const {override,fixBabelImports} = require('customize-cra');
module.exports = override(
 fixBabelImports('import',{
        libraryName:'antd',
        libraryDirectory:'es',
        style:'css'
    })
)

3.在App.js文件中,进行局部导入

import { Button } from "antd";

4.修改配置后,重启服务



聪明式组件和傻瓜式组件

聪明组件又称为容器组件,负责数据获取

傻瓜组件又称为展示组件,负责根据props显示信息内容

优势

1.逻辑和内容展示分离

2.重复性高

3.复用性高

4.易于测试

案例

在/react组件化/02_component/src 目录下创建components文件夹,然后再在该文件夹下新建一个评论列表(ComponentList.js)文件。

// CommentList.js
import React,{ Component } from 'react'

// 此时Comment 就充当傻瓜式组件
function Comment(props){
    const {id,content,author} = props.comments;
    return (
     <div>
         <p>{id}</p>
         <p>{author}</p>
         <p>{content}</p>
        </div>
    )
}


// 此时 Component 就充当聪明式组件
export default class CommentList extends Component{
    constructor(props){
        super(props);
        this.state = {
            comments:[]
        }
    }
    componentDidMount(){
        setTimeout(() => {
            this.setState({
                comments:[
                    {
                        id:1,
                        author:'facebook',
                        content:'react非常好'
                    },
                    {
                        id:2,
                        author:'尤雨溪',
                        content:'Vue更好'
                    }
                ]
            })
        },1000);
    }
    render(){
        return(
         <div>
            {
                this.state.comment.map((item,i)=>{
            return (
             <Comment key={item.id} comment={item} />
            )
        })
            }
            </div>
        )
    }
}

最后不要忘记在App.js文件中引入上面的组件

// App.js
import ComponentList from './components/CommentList'

function App(){
    return (
     <div className="App">
         <ComponentList></ComponentList>
        </div>
    )
}


扫描二维码推送至手机访问。

版权声明:本文由雨源发布,如需转载请注明出处。

本文链接:http://www.yfwork.xyz/?id=8

分享给朋友:
返回列表

上一篇:sql注入

下一篇:pyecharts基础

“React基础学习” 的相关文章

b站视频爬取案例

b站视频爬取案例

import requests from lxml import etree import json if __name__ == '__main__':    ...

python爬取下载腾讯视频

python爬取下载腾讯视频

2025-04-16_120348.pdf原文地址:https://blog.csdn.net/weixin_73080494/article/details/142530727?ops_request_misc=%257B%2522request%255Fid%2522%253A%252225d8...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。