react简单学习

引言

React,是Facebook开源的一个用于构建用户界面的JavaScript库,据说就和写js一样(我的js好像不太扎实QAQ),学了React后还可以用React Native来编写原生Android和IOS应用(据说挺热门的,准备下一步学这个)

React特点(抄的别人的)

  1. 声明式设计 −React采用声明范式,可以轻松描述应用。
  2. 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。(这里应该指的是虚拟DOM)
  3. 灵活 −React可以与已知的库或框架很好地配合。
  4. JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  5. 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  6. 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

HelloWorld

废话不多说,HelloWorld整起。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- React核心库 -->
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <!-- React操作DOM -->
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <!-- Babel -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>

    <div id="test"></div>


    <script type="text/babel">
        const element = (
            <div>
                <h2>Hello World!</h2>
            </div>
        )
        // 渲染
        ReactDOM.render(element,document.getElementById("test"))
    </script>
</body>
</html>

好大的HelloWorld(浏览器截图快捷键:Ctrl + Shift + X)
在这里插入图片描述
这里编写代码使用的语法是jsx(javascript的一种语法扩展),其实和js差不多,能在js中写HTML代码了,代码运行时会自动转成js代码

jsx中可以写表达式,但是不能写没有返回值的语句,例如:if,for

接下来鼠鼠就不说废话了,开始写!!!

列表渲染

    <script type="text/babel">
        const dataList = ["张三","李四","王五"]
        const element = (
            <div>
                <h2>Hello World!</h2>
                <ul>
                    {
                    	/* 如果是首部插入元素,会导致全部元素重新渲染 */
                        dataList.map((item,index) => <li key={index}>{item}</li>)
                    }
                </ul>
            </div>
        )
        ReactDOM.render(element,document.getElementById("test"))
    </script>

在这里插入图片描述

手动创建项目

先准备好项目结构
在这里插入图片描述
然后依次执行以下命令:

  • npm init -y (会生成package.json文件)
  • npm install react react-dom react-scripts -S(react相关依赖)
    然后在package.json文件中添加以下内容:
"start": "react-scripts start",

在这里插入图片描述
然后输入npm start或者点击启动符号就可以启动了。

脚手架创建项目

先用create-react-app创建一个项目:

要用管理员启动命令行,node版本也有要求
在这里插入图片描述

脚手架创建的项目结构:
在这里插入图片描述

组件

React中定义组件的方式有两种:函数式组件和类式组件。
函数式组件:

function App() {
  return (
      <div>
        <h2>Hello World!</h2>
      </div>
  );
}

export default App;

类式组件:

import './App.css';
import {Component} from "react";

class App extends Component{
  render(){
    return (
        <div>
          <h2>Hello World!</h2>
        </div>
    );
  }
}

export default App;

引入其他组件:

src/App.js

import './App.css';
import React, {Component} from "react";
import Child1 from "./components/child1";

class App extends Component{
  render(){
    return (
        <div>
            <Child1 />
        </div>
    );
  }
}

export default App;

components/child1/index,jsx

const Child1 = () => {

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)
    }

    const handleButtonClick = (str) => {
        return (e) => {
            console.log(e.target,str)
        }
    }

    return (
        <>
            <input type="text" onBlur={handleClick} />
            <button onClick={handleButtonClick("你干嘛")}>点我</button>
        </>
    )
}

export default Child1

事件

React中的事件和HTML中的事件很相似,React中事件采用的是驼峰命名法。

React事件属性需要传递的是函数对象,而不是函数的返回值

const Child1 = () => {

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)
    }

    return (
        <>
            <input type="text" onBlur={handleClick} />
        </>
    )
}

export default Child1

在这里插入图片描述
如果需要传参数:

const Child1 = () => {

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)
    }

    const handleButtonClick = (str) => {
        return (e) => {
            console.log(e.target,str)
        }
    }

    return (
        <>
            <input type="text" onBlur={handleClick} />
            <button onClick={handleButtonClick("你干嘛")}>点我</button>
        </>
    )
}

export default Child1

在这里插入图片描述

props

props用于父子组件传递参数:

App.js

import './App.css';
import React, {Component} from "react";
import Child1 from "./components/child1";

class App extends Component{
  render(){
    return (
        <div>
            <Child1 userInfo={{
                name: "张三",
                age: 18,
                sex: "男"
            }} />
        </div>
    );
  }
}

export default App;

Child1/index.jsx

const Child1 = (props) => {

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)
    }

    const handleButtonClick = (str) => {
        return (e) => {
            console.log(e.target,str)
        }
    }

    const {userInfo} = props

    return (
        <>
            <input type="text" onBlur={handleClick} />
            <button onClick={handleButtonClick("你干嘛")}>点我</button>
            <hr/>
            <span>{`${userInfo.name},${userInfo.age},${userInfo.sex}`}</span>
        </>
    )
}

export default Child1

props中的属性是只读的,无法修改

state

state一般用于存储和视图有关联的数据,数据驱动视图发生变化,每个组件都有他自己的state。

import {useState} from "react";

const Child1 = (props) => {

    const {userInfo} = props

    const [date,setDate] = useState(new Date().toLocaleTimeString())

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)

    }
    const handleButtonClick = (str) => {
        return (e) => {
            console.log(e.target,str)
        }
    }

    const refreshDate = () => {
        setDate(new Date().toLocaleTimeString())
    }

    return (
        <>
            <input type="text" onBlur={handleClick} />
            <button onClick={handleButtonClick("你干嘛")}>点我</button>
            <hr/>
            <span>{`${userInfo.name},${userInfo.age},${userInfo.sex}`}</span>
            <hr/>
            <span>最新时间:{date}</span>
            <button onClick={refreshDate}>刷新</button>
        </>
    )
}

export default Child1

点击按钮可以发现时间发生变化了。
但是如果修改date的这个方法中涉及到一些异步请求之类的逻辑,可能会得到意想不到的结果。
例如:

import {useState} from "react";

const Child1 = (props) => {

    const {userInfo} = props

    const [date,setDate] = useState(new Date().toLocaleTimeString())
    const [count,setCount] = useState(0)

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)

    }
    const handleButtonClick = (str) => {
        return (e) => {
            console.log(e.target,str)
        }
    }

    const refreshDate = () => {
        setDate(new Date().toLocaleTimeString())
    }

    const incrementCount = () => {
        console.log("点击了")
        setTimeout(() => {
            setCount(count + 1)
        },1000)
    }

    return (
        <>
            <input type="text" onBlur={handleClick} />
            <button onClick={handleButtonClick("你干嘛")}>点我</button>
            <hr/>
            <span>{`${userInfo.name},${userInfo.age},${userInfo.sex}`}</span>
            <hr/>
            <span>最新时间:{date}</span>
            <button onClick={refreshDate}>刷新</button>
            <hr/>
            <span>当前值:{count}</span>
            <button onClick={incrementCount}>+</button>
        </>
    )
}

export default Child1

在这里插入图片描述
可以发现我一秒钟内点击了3次,但是值却只增加了1,当需要用到之前的值时,我们可以换一种写法。

    const incrementCount = () => {
        console.log("点击了")
        setTimeout(() => {
            setCount(preCount => preCount + 1)
        },1000)
    }

在这里插入图片描述
可以发现现在点击增加的值是正常的。

ref

ref为我们提供了一种操作DOM的方式

import {useState,useRef} from "react";

const Child1 = (props) => {

    const {userInfo} = props
    const [date,setDate] = useState(new Date().toLocaleTimeString())
    const [count,setCount] = useState(0)
    const inputRef = useRef()

    const handleClick = (e) => {
        console.log("你干嘛~",e.target.value)

    }
    const handleButtonClick = (str) => {
        return (e) => {
            console.log(e.target,str)
        }
    }

    const refreshDate = () => {
        setDate(new Date().toLocaleTimeString())
    }

    const incrementCount = () => {
        console.log("点击了")
        setTimeout(() => {
            setCount(preCount => preCount + 1)
        },1000)
    }

    const handleBlur = () => {
        console.log(inputRef.current.value)
    }

    return (
        <>
            <input type="text" onBlur={handleClick} />
            <button onClick={handleButtonClick("你干嘛")}>点我</button>
            <hr/>
            <span>{`${userInfo.name},${userInfo.age},${userInfo.sex}`}</span>
            <hr/>
            <span>最新时间:{date}</span>
            <button onClick={refreshDate}>刷新</button>
            <hr/>
            <span>当前值:{count}</span>
            <button onClick={incrementCount}>+</button>
            <hr/>
            <input ref={inputRef} type="text" onBlur={handleBlur}/>
        </>
    )
}

export default Child1

在这里插入图片描述

非必要的情况下,最好不要操作原生DOM对象

form

表单处理:

import React, {useState} from "react";

const Form = () => {

    const [form,setForm] = useState({
        userName: "",
        password: ""
    })

    const setUserName = (e) => {
        setForm(Object.assign(form,{userName: e.target.value}))
    }

    const setPassword = (e) => {
        setForm(Object.assign(form,{password: e.target.value}))
    }

    const handleSubmit = (e) => {
        console.log(form)

        e.preventDefault()
    }

    return (
        <>
            <form onSubmit={handleSubmit}>
                用户名:<input type="text" onChange={setUserName} />
                <br/>
                密码:<input type="text" onChange={setPassword} />
                <input type="submit" value="提交" />
            </form>
        </>
    )
}

export default Form

css样式

import React, {useState} from "react"

const Weather = () => {

    const [isHot,setWeather] = useState(true)

    return (
        <>
            <span style={{backgroundColor: isHot ? "red" : "green"}}>当前天气:{isHot ? "炎热" : "寒冷"}</span>
            <button onClick={() => {setWeather(!isHot)}}>点我</button>
        </>
    )
}

export default Weather

在这里插入图片描述
css模块化引入:必须以.module.css结尾

weather.module.css

.weather {
    font-size: 25px;
}

index.jsx

import React, {useState} from "react"
import weather from "./weather.module.css"

const Weather = () => {

    const [isHot,setWeather] = useState(true)

    return (
        <>
            <span className={weather.weather} style={{backgroundColor: isHot ? "red" : "green"}}>当前天气:{isHot ? "炎热" : "寒冷"}</span>
            <button onClick={() => {setWeather(!isHot)}}>点我</button>
        </>
    )
}

export default Weather

context

react还为我们提供了一种组件之间的通信方式,只需要在最外层的组件设置了属性,内层所有子组件都可访问到。

context/index.jsx

import {createContext} from "react";
// 用来创建context,可以传入一个参数,用来指定初始值
const TestContext = createContext()

export default TestContext

useContext:传入Context对象,可以获得Context对象存储的数据

son/index.jsx

import React, {useContext} from "react"
import TestContext from "../../../../store/context/TestContext";

const Son = () => {

    const ctx = useContext(TestContext)

    return (
        <>
            <span>我是Son,{`${ctx.firstName},${ctx.location}`}</span>
        </>
    )
}

export default Son

father/index.jsx

import React, {useContext} from "react"
import Son from "./son";
import TestContext from "../../../store/context/TestContext";

const Father = () => {

    const ctx = useContext(TestContext)

    return (
        <>
            <span>我是Father,{`${ctx.firstName},${ctx.location}`}</span>
            <hr/>
            <Son />
        </>
    )
}

export default Father

grandPa/index.jsx

import React, {useContext} from "react"
import Father from "./father";
import TestContext from "../../store/context/TestContext";

const GrandPa = () => {

    const ctx = useContext(TestContext)

    return (
        <>
            <span>我是GrandPa,{`${ctx.firstName},${ctx.location}`}</span>
            <hr/>
            <Father />
        </>
    )
}

export default GrandPa

App.js

import './App.css';
import React, {Component} from "react";
import Child1 from "./components/child1";
import Form from "./components/form";
import Weather from "./components/weather";
import GrandPa from "./components/grandPa";
import TestContext from "./store/context/TestContext";

class App extends Component{
  render(){
    return (
        <div>
            <Child1 userInfo={{
                name: "张三",
                age: 18,
                sex: "男"
            }} />
            <hr/>
            <Form />
            <hr/>
            <Weather />
            <hr/>
            <TestContext.Provider value={{firstName: "欧阳",location: "鵗"}}>
                <GrandPa />
            </TestContext.Provider>
        </div>
    );
  }
}

export default App;

useEffect

useEffect方法会在每次DOM渲染完毕之后执行,这里可以写一些渲染之后需要处理的业务逻辑。

import React, {useContext, useEffect, useState} from "react"
import TestContext from "../../../../store/context/TestContext";

const Son = () => {

    const ctx = useContext(TestContext)

    const [count,setCount] = useState(0)

    useEffect(() => {
        // 每次组件渲染之后执行
        console.log("DOM渲染完了")
    })

    return (
        <>
            <span>我是Son,{`${ctx.firstName},${ctx.location}`}</span>
            <span>count:{count}</span>
            <button onClick={() => {setCount(count + 1)}}>+</button>
        </>
    )
}

export default Son

在这里插入图片描述
如果前后两次执行effect会互相影响,就需要清除之前effect带来的影响:而且不是每次更新都要调用effect方法,第二个参数指定只有那些数据发生变化才会调用useEffect方法

import React, {useContext, useEffect, useState} from "react"
import TestContext from "../../../../store/context/TestContext";

const Son = () => {

    const ctx = useContext(TestContext)

    const [count,setCount] = useState(0)

    const [num,setNum] = useState(0)

    useEffect(() => {
        console.log("useEffect")
        const timer = setInterval(() => {
            // 每次组件渲染之后执行
            console.log("DOM渲染完了")
        },1000)

        return () => {
            // 清除之前effect造成的影响
            clearInterval(timer)
        }
        // 设置只有num参数变化才调用effect方法
    },[num])

    return (
        <>
            <span>我是Son,{`${ctx.firstName},${ctx.location}`}</span>
            <span>count:{count}</span>
            <button onClick={() => {setCount(count + 1)}}>+</button>
            <span>count:{num}</span>
            <button onClick={() => {setNum(num + 1)}}>+</button>
        </>
    )
}

export default Son

reduer

之前修改数据都是setState,对于一些简单地数据还好,当数据比较复杂时,可以使用Reducer

import React, {useReducer} from "react"

const userReducer = (state,action) => {
    switch (action.type) {
        case "userName":
            return {
                ...state,
                userName: state.userName = "李四"
            }
        case "password":
            return {
                ...state,
                password: state.password = "QWERTY"
            }
        default:
            return {}
    }
}

const TestReducer = () => {

    const [userInfo,dispatch] = useReducer(userReducer,{
        userName: "张三",
        password: "123456"
    })

    return (
        <>
            <span>{userInfo.userName} = {userInfo.password}</span>
            <input type="text" onBlur={() => {dispatch({type:"userName"})}} />
            <input type="password" onBlur={() => {dispatch({type: "password"})}} />
        </>
    )
}

export default TestReducer

memo

当父组件重新渲染时,对应的子组件也会重新渲染,循环往下,但是有时候,只有父组件发生了变化,子组件和渲染之前并无差别,那么这时候子组件没有必要重新渲染,React为我们提供了可以缓存组件的选择。

export default React.memo(Father)

fetch

fetch是浏览器自带的一种发送请求的方式,不用引入任何库

import React, {useContext, useEffect} from "react"
import Son from "./son";
import TestContext from "../../../store/context/TestContext";

const Father = () => {

    const ctx = useContext(TestContext)

    useEffect(() => {
        fetch("http://localhost:3000/user/student")
            .then(res => res.json())
            .then(data => {
                console.log("data",data)
            })
    })

    return (
        <>
            <span>我是Father,{`${ctx.firstName},${ctx.location}`}</span>
            <hr/>
            <Son />
        </>
    )
}

export default React.memo(Father)

在这里插入图片描述
可以发现请求到数据了

自定义钩子

有时候我们需要根据公司业务去定制化一些可复用的代码,react允许我们提供了自定义钩子,需要满足三个要求:

  1. 以use开头
  2. 正常调用react的其他钩子
  3. 在其他组件中引用钩子
import React, {useState} from "react"

const useFetch = (url,requestArgs = {}) => {

    // 数据Loading
    const [loading,setLoading] = useState(false)
    // 请求数据
    const [data,setData] = useState()
    // 错误信息
    const [err,setErr] = useState(null)

    async function fetchData(){
        try {
            setLoading(true)
            setErr(null)

            const res = await fetch(url,requestArgs)

            if(!res.ok){
                throw new Error("未知错误,请反馈管理员")
            }

            const data = await res.json()

            setData(data)

        }catch (e) {
            setErr(e)
        }finally {
            setLoading(false)
        }
    }
    return {loading,data,err,fetchData}
}

export default useFetch

在组件中引用:

import React, {useContext, useEffect} from "react"
import Son from "./son";
import TestContext from "../../../store/context/TestContext";
import useFetch from "../../../hooks/useFetch";

const Father = () => {

    const ctx = useContext(TestContext)

    const {data,loading,err,fetchData} = useFetch("http://localhost:3000/user/student")

    useEffect(() => {
        fetchData()
    },[])
    // 只运行一次,不添加就会一直无限调用

    return (
        <>
            <span>我是Father,{`${ctx.firstName},${ctx.location}`}</span>
            <hr/>
            <Son />
        </>
    )
}

export default React.memo(Father)

依然能正常访问到
依然能正常访问到

redux

老版使用方式:
下载依赖:

npm install -S redux react-redux

carReducer/index.jsx

const catReducer = (state = {
    name: "阿猫",
    age: 1
},action) => {
    switch (action.type) {
        case "SET_NAME":
            return {
                ...state,
                name: action.payload
            }
        case "SET_AGE":
            return {
                ...state,
                age: state.age + action.payload
            }
        default:
            return {
                ...state
            }
    }
}

export default catReducer

reactReducer/index.jsx

import React from "react"
import {useDispatch, useSelector} from "react-redux";

const TestReactReducer = () => {

    const state = useSelector(state => state)

    const dispatch = useDispatch()

    return (
        <>
            <span>我是{state.name},我今年{state.age}岁了</span>
            <button onClick={() => {dispatch({type:"SET_NAME",payload:"大猫"})}}>改名字</button>
            <button onClick={() => {dispatch({type:"SET_AGE",payload:1})}}>长大</button>
        </>
    )
}

export default TestReactReducer

App.js

import './App.css';
import React, {Component} from "react";
import Child1 from "./components/child1";
import Form from "./components/form";
import Weather from "./components/weather";
import GrandPa from "./components/grandPa";
import TestContext from "./store/context/TestContext";
import TestReducer from "./components/testReducer";
import TestReactReducer from "./components/reactReducer"
import catReducer from "./components/catReducer";
import {Provider, useSelector} from "react-redux";
import {createStore} from "redux";

// 老版创建store方式
const store = createStore(catReducer)

store.subscribe(() => {
    console.log("state发生变化了 ")
})

class App extends Component{
  render(){
    return (
        <div>
            <Child1 userInfo={{
                name: "张三",
                age: 18,
                sex: "男"
            }} />
            <hr/>
            <Form />
            <hr/>
            <Weather />
            <hr/>
            <TestContext.Provider value={{firstName: "欧阳",location: "鵗"}}>
                <GrandPa />
            </TestContext.Provider>
            <hr/>
            <TestReducer />
            <Provider store={store}>
                <TestReactReducer />
            </Provider>

        </div>
    );
  }
}

export default App;

如果是多个reduer:

dogReducer/index.jsx

const dogReducer = (state = {
    name: "阿狗",
    age: 2
},action) => {
    switch (action.type) {
        case "SET_DOG_NAME":
            return {
                ...state,
                name: action.payload
            }
        case "SET_DOG_AGE":
            return {
                ...state,
                age: state.age + action.payload
            }
        default:
            return {
                ...state
            }
    }
}

export default dogReducer

reactReducer/index.jsx

import React from "react"
import {useDispatch, useSelector} from "react-redux";

const TestReactReducer = () => {

    const cat = useSelector(state => state.cat)
    const dog = useSelector(state => state.dog)

    const dispatch = useDispatch()

    return (
        <>
            <span>我是{cat.name},我今年{cat.age}岁了</span>
            <button onClick={() => {dispatch({type:"SET_CAT_NAME",payload:"大猫"})}}>改名字</button>
            <button onClick={() => {dispatch({type:"SET_CAT_AGE",payload:1})}}>长大</button>
            <hr/>
            <span>我是{dog.name},我今年{dog.age}岁了</span>
            <button onClick={() => {dispatch({type:"SET_DOG_NAME",payload:"大狗"})}}>改名字</button>
            <button onClick={() => {dispatch({type:"SET_DOG_AGE",payload:2})}}>长大</button>
        </>
    )
}

export default TestReactReducer

App.js

const reducers = combineReducers({
    cat: catReducer,
    dog: dogReducer
})

const store = createStore(reducers)

store.subscribe(() => {
    console.log("state发生变化了 ")
})

router

通过路由,我们可以做到让url地址映射react组件。
安装依赖:

npm install react-router-dom@5 -S
import {Link,Route} from "react-router-dom";
            <Link to="/about">About</Link>
            <br/>
            <Link to="/home">Home</Link>
            <hr/>
            <Route path="/about" component={About} />
            <Route path="/home" component={Home} />

path可以匹配多个url:

            <Link to="/about1">About1</Link>
            <br/>
            <Link to="/about2">About2</Link>
            <br/>
            <Link to="/home">Home</Link>
            <hr/>
            <Route path={["/about1","/about2"]} component={About} />
            <Route path="/home" component={Home} />

传递参数:

            <Link to="/about1/1">About1</Link>
            <br/>
            <Link to="/about2">About2</Link>
            <br/>
            <Link to="/home">Home</Link>
            <hr/>
            <Route path={["/about1/:id","/about2"]} component={About} />
            <Route path="/home" component={Home} />

about/index.jsx

import React from "react"
import {useParams} from "react-router-dom"

const About = () => {

    const {id} = useParams()

    console.log("接收到id:" + id)

    return (
        <>
            <h2>我是About</h2>
        </>
    )
}

export default About

在这里插入图片描述
可以发现接收到了。
react-router-dom@6版本:

npm install react-router-dom@6 -S
            <Link to="/about">About</Link>
            <br/>
            <Link to="/home">Home</Link>
            <br/>
            <hr/>
            <Routes>
                <Route path={"/"} element={<About />} />
                <Route path={"/about"} element={<About />} />
                <Route path="/home" element={<Home />} />
            </Routes>

嵌套路由:

App.js

            <Link to="/about">About</Link>
            <br/>
            <Link to="/about/123">AboutChild</Link>
            <br/>
            <Link to="/home">Home</Link>
            <br/>
            <hr/>
            <Routes>
                <Route path={"/"} element={<About />} />
                <Route path={"/about"} element={<About />}>
                    <Route path=":id" element={<AboutChild />} />
                </Route>
                <Route path="/home" element={<Home />} />
            </Routes>

about/child/index.jsx

import React from "react"
import {useParams} from "react-router-dom"

const AboutChild = () => {

    const {id} = useParams()

    console.log("child接收到id:" + id)

    return (
        <>
            <h2>我是AboutChild</h2>
        </>
    )
}

export default AboutChild

结语:学到这里纯属爱好,有空再更新!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值