【前端学习】React学习笔记


前言

前端开发库学习笔记,仅供参考交流,如有侵权,请联系删除。


React

1 简介

React 是一个流行的 JavaScript 库,用于为网页或应用程序构建可重用的组件驱动的用户界面。

React 将 HTML 与 JavaScript 结合在了一起,以此创建出一个新的标记语言 JSX。React 还使得管理整个应用程序的数据流变得更容易。

2 笔记

创建一个简单的JSX元素

React 使用名为 JSX 的 JavaScript 语法扩展,可以直接在 JavaScript 中编写 HTML。 这有几个好处。 可以在 HTML 中使用 JavaScript 的完整程序功能,并有助于保持代码的可读性。

因为 JSX 是 JavaScript 的语法扩展,所以实际上可以直接在 JSX 中编写 JavaScript。 要做到这一点,只需在花括号中包含希望被视为 JavaScript 的代码:{ ‘this is treated as JavaScript code’ }(这被视为 JavaScript 代码)。

由于浏览器不能解析 JSX,因此必须将 JSX 代码编译为 JavaScript。 在这个过程中,转换器 Babel 是一个很受欢迎的工具。

const JSX = <h1>Hello JSX!</h1>;

创建一个复杂的 JSX 元素

关于嵌套的 JSX,必须返回单个元素。用父元素包裹所有其他级别的嵌套元素。

<div>
  <p>Paragraph One</p>
  <p>Paragraph Two</p>
  <p>Paragraph Three</p>
</div>

在JSX中添加注释

const JSX = (
  <div>
  {/*这里是注释*/}
    <h1>This is a block of JSX</h1>
    <p>Here's a subtitle</p>
  </div>
);

渲染 HTML 元素为 DOM 树

const JSX = (
  <div>
    <h1>Hello World</h1>
    <p>Lets render this to the DOM</p>
  </div>
);
// 在这行下面添加代码
ReactDOM.render(JSX,document.getElementById('challenge-node'));

render函数的第一个参数是要渲染的React元素或组件,第二个参数是组件将要渲染到的DOM节点。

在 JSX 中定义一个 HTML Class

JSX 的一个关键区别是你不能再使用 class 这个单词来做为 HTML 的 class 名。 这是因为 class 是 JavaScript 中的关键字。 而 JSX 使用 className 来代替。

事实上,JSX 中所有 HTML 属性和事件引用的命名约定都变成了驼峰式。 例如,JSX 中的单击事件是 onClick,而不是 onclick。 同样,onchange 变成了onChange。 虽然这是一个微小的差异,但请你一定要记住。

了解自闭合 JSX 标签

任何 JSX 元素都可以使用自闭合标签编写,并且每个元素都必须关闭。 例如,为了通过编译换行标签必须始终编写为 <br />。 另一方面 <div> 可以写成 <div /> 或者 <div></div>。 不同之处在于,在第一个语法版本中,无法在 <div /> 中包含任何内容。 在后面的挑战中你会发现,这种语法在渲染 React 组件时非常有用。

创建一个无状态的函数组件

const MyComponent = function() {
  // 修改这行下面的代码
  return (
    <div>zzzz</div>
  );
  // 修改这行上面的代码
}

有两种方法可以创建 React 组件。 第一种方法是使用 JavaScript 函数。 以这种方式定义组件会创建无状态函数组件。

要用函数创建组件,只需编写一个返回 JSX 或 null 的 JavaScript 函数。 需要注意的一点是,React 要求你的函数名以大写字母开头。

创建一个React组件

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    // 修改这行下面的代码
    return (
      <div><h1>Hello React!</h1></div>
    )
    // 修改这行上面的代码
  }
};

创建了一个ES6类MyComponent ,它扩展了React.Component类,因此MyComponent 类现在可以访问许多有用的React功能,例如本地状态和生命周期钩子。

MyComponent 类定义了一个调用super()方法的constructor。它使用super()调用父类的构造函数,即本例中的React.Component。

构造函数是使用 class 关键字创建的特殊方法,它在实例初始化之前调用。 最佳做法是在组件的 constructor 里调用 super,并将 props 传递给它们, 这样可以保证组件能够正确地初始化。

用组合的方式创建一个 React 组件

const ChildComponent = () => {
  return (
    <div>
      <p>I am the child</p>
    </div>
  );
};

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h1>I am the parent</h1>
        { /* 修改这行下面的代码 */ }

          <ChildComponent />

        { /* 修改这行上面的代码 */ }
      </div>
    );
  }
};

将class组件渲染到DOM树

class TypesOfFood extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h1>Types of Food:</h1>
        {/* 修改这行下面的代码 */}
        <Fruits/>
        <Vegetables/>
        {/* 修改这行上面的代码 */}
      </div>
    );
  }
};

// 修改这行下面的代码
ReactDOM.render(<TypesOfFood/>,document.getElementById('challenge-node'))

对于 JSX 元素,传入的是要渲染的元素的名称。 但是,对于 React 组件,需要使用与渲染嵌套组件相同的语法,即传入<TypesOfFood/>

将 Props 传递给无状态函数组件

const CurrentDate = (props) => {
  return (
    <div>
      { /* 修改这行下面的代码 */ }
      <p>The current date is: {props.date}</p>
      { /* 修改这行上面的代码 */ }
    </div>
  );
};

class Calendar extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h3>What date is it?</h3>
        { /* 修改这行下面的代码 */ }
        <CurrentDate date={Date()}/>
        { /* 修改这行上面的代码 */ }
      </div>
    );
  }
};

在 React 中,可以把创建的 React 支持的自定义 HTML 属性传递给组件。调用 props 这个值是常见做法,当处理无状态函数组件时,基本上可以将其视为返回 JSX 的函数的参数。 这样就可以在函数体中访问该值。 但对于类组件,访问方式会略有不同。

传递一个数组作为Props

const List = (props) => {
  { /* 修改这行下面的代码 */ }
  return <p>{props.tasks.join(',')}</p>
  { /* 修改这行上面的代码 */ }
};

class ToDo extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h1>To Do Lists</h1>
        <h2>Today</h2>
        { /* 修改这行下面的代码 */ }
        <List tasks={["walk dog","workout","read"]}/>
        <h2>Tomorrow</h2>
        <List tasks={["walk dog","workout","read"]}/>
        { /* 修改这行上面的代码 */ }
      </div>
    );
  }
};

使用默认的Props

const ShoppingCart = (props) => {
  return (
    <div>
      <h1>Shopping Cart Component</h1>
    </div>
  )
};
// 修改这行下面的代码
ShoppingCart.defaultProps = {
  items:0
}

在组件ShoppingCart上定义默认props,它指定一个items prop,其值为0。

覆盖默认的props

const Items = (props) => {
  return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
}

Items.defaultProps = {
  quantity: 0
}

class ShoppingCart extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    { /* 修改这行下面的代码 */ }
    return <Items quantity={10}/>
    { /* 修改这行上面的代码 */ }
  }
};

由于 quantity 的值是整数,所以它不会加引号,但应该用花括号括起来, 例如{100}。 这个语法告诉 JSX 直接将花括号中的值解释为 JavaScript。

使用 PropTypes 来定义 Props 的类型

const Items = (props) => {
  return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
};

// 修改这行下面的代码
Items.propTypes = {
  quantity:PropTypes.number.isRequired
}
// 修改这行上面的代码

Items.defaultProps = {
  quantity: 0
};

class ShoppingCart extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <Items />
  }
};

当提前知道 prop 的类型时,最佳实践是设置其 propTypes。 当数据是任何其它类型时,都会抛出警告。

  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

使用this.props 访问props

class App extends React.Component {
  constructor(props) {
    super(props);

  }
  render() {
    return (
        <div>
            { /* 修改这行下面的代码 */ }
            <Welcome name={"Cat"}/>
            { /* 修改这行上面的代码 */ }
        </div>
    );
  }
};

class Welcome extends React.Component {
  constructor(props) {
    super(props);

  }
  render() {
    return (
        <div>
          { /* 修改这行下面的代码 */ }
          <p>Hello, <strong>{this.props.name}</strong>!</p>
          { /* 修改这行上面的代码 */ }
        </div>
    );
  }
};

倘若接收 prop 的子组件不是无状态函数组件,而是一个 ES6 类组件的时候,要访问类组件中的 props,需要在在访问它的代码前面添加 this。

任何时候,如果要引用类组件本身,可以使用 this 关键字。

创建一个有状态的组件

class StatefulComponent extends React.Component {
  constructor(props) {
    super(props);
    // 只修改这一行下面的代码
    this.state = {
      firstName:'Xiaoming'
    }
    // 只修改这一行上面的代码
  }
  render() {
    return (
      <div>
        <h1>{this.state.firstName}</h1>
      </div>
    );
  }
};

React 中最重要的主题之一是 state。 state 包含应用程序需要了解的任何数据,这些数据可能会随时间而变化。 应用程序能够响应 state 的变更,并在必要时显示更新后的 UI。

可以在组件的整个生命周期内访问 state 对象, 可以更新它、在 UI 中渲染它,也可以将其作为 props 传递给子组件。这里通过{this.state.firstName}渲染状态。

以另一种方式在用户界面中渲染状态

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'freeCodeCamp'
    }
  }
  render() {
    // 修改这行下面的代码
    const name = this.state.name
    // 修改这行上面的代码
    return (
      <div>
        { /* 修改这行下面的代码 */ }
        <h1>{name}</h1>
        { /* 修改这行上面的代码 */ }
      </div>
    );
  }
};

用this.setState设置状态

this.setState()方法,传入键值对的对象,其中键是state属性,值是更新后的state数据。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'Initial State'
    };
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    // 修改这行下面的代码
    this.setState({
      name:'React Rocks!'
    });
    // 修改这行上面的代码
  }
  render() {
    return (
      <div>
        <button onClick={this.handleClick}>Click Me</button>
        <h1>{this.state.name}</h1>
      </div>
    );
  }
};

React要求永远不要直接修改state,而是在state发生改变时始终使用this.setState()。此外,React可以批量处理多个state更新以提高性能,这意味着通过setSate方法进行的state更新可以是异步的。

handleClick() {
  this.setState((prevState) => {
    return {
      counter: prevState.counter + 1
    };
  });

  console.log("counter", this.state.counter);
}

在这里,我们将一个函数作为 setState 方法的第一个参数传递,并返回一个新的状态对象,其中counter 在 counter的上一个值的基础上增加1。这样可以正确地获得UI上 counter 的更新值。 但在控制台中获取的是以前的 counter 值,尽管我们在调用 this.setState 之后添加了console.log,这便是异步的表现。

handleClick() {
  this.setState(
    (prevState) => {
      return {
        counter: prevState.counter + 1
      };
    },
    () => console.log("counter", this.state.counter)
  );
}

尽管React提供了一个回调函数来立即获取更新后的状态值,但建议只在快速测试或记录日志时使用它。React建议使用componentDidUpdate方法:

componentDidUpdate(prevProps, prevState) {
  if (prevState.counter !== this.state.counter) {
    // do something
    console.log("counter", this.state.counter);
  }
}

学着学着发现不太懂了,可能是内容太多了,先学到这里。

将this绑定到Class方法上

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "Hello"
    };
    // 修改这行下面的代码
    this.handleClick = this.handleClick.bind(this);
    // 修改这行上面的代码
  }
  handleClick() {
    this.setState({
      text: "You clicked!"
    });
  }
  render() {
    return (
      <div>
        { /* 修改这行下面的代码 */ }
        <button onClick={this.handleClick}>Click Me</button>
        { /* 修改这行上面的代码 */ }
        <h1>{this.state.text}</h1>
      </div>
    );
  }
};

让类方法访问this,使用this.handleClick = this.handleClick.bind(this);显式绑定。

使用 State 切换元素

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
this.setState(state => ({
  counter: state.counter + 1
}));

给 setState 传入一个函数,这个函数可以访问 state 和 props。 给 setState 传入函数可以保证 state 和 props 是正确的值,即上一个状态。

创建一个可以控制的表单

class MyForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      submit: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
  handleSubmit(event) {
    // 修改这行下面的代码
    event.preventDefault();
    this.setState({
      submit: this.state.input
    });
    // 修改这行上面的代码
  }
  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          {/* 修改这行下面的代码 */}
          <input value={this.state.input} onChange={this.handleChange}/>
          {/* 修改这行上面的代码 */}
          <button type='submit'>Submit!</button>
        </form>
        {/* 修改这行下面的代码 */}
        <h1>{this.state.submit}</h1>
        {/* 修改这行上面的代码 */}
      </div>
    );
  }
}

在提交处理程序中调用event.preventDefault();,防止将会刷新网页的默认的表单提交行为。

生命周期方法

使用生命周期方法 componentWillMount

当组件被挂载到 DOM 时,componentWillMount() 方法在 render() 方法之前被调用。
注意: componentWillMount 生命周期方法会在版本 16.X 废弃,在版本 17 移除。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  componentWillMount() {
    // 修改这行下面的代码
    console.log("今天周一")
    // 修改这行上面的代码
  }
  render() {
    return <div />
  }
};
使用生命周期方法:componentDidMount

某些时候,大多数 web 开发人员需要调用 API 接口来获取数据。 如果正在使用 React,知道在哪里执行这个动作是很重要的。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      activeUsers: null
    };
  }
  componentDidMount() {
    setTimeout(() => {
      this.setState({
        activeUsers: 1273
      });
    }, 2500);
  }
  render() {
    return (
      <div>
        {/* 修改这行下面的代码 */}
        <h1>Active Users:{this.state.activeUsers} </h1>
        {/* 修改这行上面的代码 */}
      </div>
    );
  }
}

React 的最佳实践是在生命周期方法 componentDidMount() 中对服务器进行 API 调用或任何其它调用。 将组件装载到 DOM 后会调用此方法。 此处对 setState() 的任何调用都将触发组件的重新渲染。 在此方法中调用 API 并用 API​​ 返回的数据设置 state 时,一旦收到数据,它将自动触发更新。

vue的最佳实践是在created()里吗?现在工作中好像只在这个方法中调用过api以获取数据,其他的生命周期方法中确实比较少见…

添加事件侦听器

componentDidMount() 方法也是添加特定功能所需的任何事件监听器的最佳位置。

React提供了一个合成事件系统,它封装了浏览器中的事件系统。不管用户用的是什么浏览器,合成事件系统的行为都完全相同–即使不同浏览器之间的本地事件的行为可能不同。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: ''
    };
    this.handleEnter = this.handleEnter.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  // 修改这行下面的代码
  componentDidMount() {
    document.addEventListener(this.keydown ,this.handleKeyPress);
  }
  componentWillUnmount() {
    document.removeEventListener(this.keydown
    ,this.handleKeyPress)
  }
  // 修改这行上面的代码
  handleEnter() {
    this.setState((state) => ({
      message: state.message + 'You pressed the enter key! '
    }));
  }
  handleKeyPress(event) {
    if (event.keyCode === 13) {
      this.handleEnter();
    }
  }
  render() {
    return (
      <div>
        <h1>{this.state.message}</h1>
      </div>
    );
  }
};
使用 shouldComponentUpdate 优化重新渲染

到目前为止,如果任何组件接收到新的 state 或新的 props,它会重新渲染自己及其所有子组件。 这通常是好的。 但是 React 提供了一种生命周期方法shouldComponentUpdate(),当子组件接收到新的 state 或 props 时,可以调用该方法,并特别声明组件是否应该更新。

class OnlyEvens extends React.Component {
  constructor(props) {
    super(props);
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('Should I update?');
    // OnlyEvens仅在其新 props 的 value 为偶数时更新
    if(nextProps.value%2 == 0){
      return true;
    }else{
      return false;
    }
    // 修改这行上面的代码
  }
  componentDidUpdate() {
    console.log('Component re-rendered.');
  }
  render() {
    return <h1>{this.props.value}</h1>;
  }
}

class Controller extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
    this.addValue = this.addValue.bind(this);
  }
  addValue() {
    this.setState(state => ({
      value: state.value + 1
    }));
  }
  render() {
    return (
      <div>
        <button onClick={this.addValue}>Add</button>
        <OnlyEvens value={this.state.value} />
      </div>
    );
  }
}

这种方法是优化性能的有效方法。 例如,默认行为是,当组件接收到新的 props 时,即使 props 没有改变,它也会重新渲染。 可以通过使用 shouldComponentUpdate() 比较 props 来防止这种情况发生。 该方法必须返回一个 boolean(布尔值),该值告诉 React 是否更新组件。 可以比较当前的 props(this.props)和下一个 props(nextProps),以确定你是否需要更新,并相应地返回 true 或 false。

介绍内联样式

class Colorful extends React.Component {
  render() {
    return (
      <div style={{color:"red",fontSize:72}}>Big Red</div>
    );
  }
};

使用style属性为JSX添加内联样式。
注意驼峰拼写 fontSize 属性。

在 React 中添加内联样式

const styles = {
  color:"purple",
  fontSize:40,
  border:'2px solid purple'
}
// 修改这行上面的代码
class Colorful extends React.Component {
  render() {
    // 修改这行下面的代码
    return (
      <div style={styles}>Style Me!</div>
    );
    // 修改这行上面的代码
  }
};

有大量样式时,可以将样式 object(对象)分配给一个常量,以保持代码组织有序。

内联样式可以给一个元素单独添加样式,实际工作中,很多时候是要给一组元素设置样式,比如把系统全部蓝色按钮的亮度调暗。

&& 代替if/else进行更加简洁的条件渲染

render() {
    // 修改这行下面的代码
    return (
       <div>
         <button onClick={this.toggleDisplay}>Toggle Display</button>
         {this.state.display && <h1>Displayed!</h1>}
       </div>
    );
  }
};
{condition && <p>markup</p>}

如果condition为true,则返回标记;如果为false,则在评估condition后操作将立即返回false,并且不返回任何内容。

可以将这些语句直接包含在 JSX 中,并通过在每个条件后面写 && 来将多个条件串在一起。 这允许你在 render() 方法中处理更复杂的条件逻辑,而无需重复大量代码,从而减少出错的可能。

使用三元表达式进行条件渲染

const inputStyle = {
  width: 235,
  margin: 5
};

class CheckUserAge extends React.Component {
  constructor(props) {
    super(props);
    // 修改这行下面的代码
    this.state = {
      input:'',
      userAge:''
    };
    // 修改这行上面的代码
    this.submit = this.submit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(e) {
    this.setState({
      input: e.target.value,
      userAge: ''
    });
  }
  submit() {
    this.setState(state => ({
      userAge: state.input
    }));
  }
  render() {
    const buttonOne = <button onClick={this.submit}>Submit</button>;
    const buttonTwo = <button>You May Enter</button>;
    const buttonThree = <button>You Shall Not Pass</button>;
    return (
      <div>
        <h3>Enter Your Age to Continue</h3>
        <input
          style={inputStyle}
          type='number'
          value={this.state.input}
          onChange={this.handleChange}
        />
        <br />
        {/* 修改这行下面的代码 */}
        {
          this.state.userAge === ''
            ? buttonOne
            : this.state.userAge >= 18
            ? buttonTwo
            : buttonThree
        }
        {/* 修改这行上面的代码 */}
      </div>
    );
  }
}

该三元表达式实现的逻辑:当页面首次加载时,将提交按钮 buttonOne 渲染到页面。 然后,当用户输入年龄并点击该按钮时,根据年龄渲染不同的按钮。 如果用户输入的数字小于18,则渲染buttonThree。 如果用户输入的数字大于或等于18,则渲染buttonTwo。

2024.5.15 上面介绍了三种条件渲染技术,其中三元运算符在React开发人员中非常流行,使用它可以在JSX中实现条件逻辑。三元运算符有三个部分,但可以将多个三元表达式组合在一起(就像上面的例子)。

创建一个简单的"To Do List"应用程序

const textAreaStyles = {
  width: 235,
  margin: 5
};

class MyToDoList extends React.Component {
  constructor(props) {
    super(props);
    // 修改这行下面的代码
    this.state = {
      userInput : "",
      toDoList :[]
    }
    // 修改这行上面的代码
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  handleSubmit() {
    const itemsArray = this.state.userInput.split(',');
    this.setState({
      toDoList: itemsArray
    });
  }
  handleChange(e) {
    this.setState({
      userInput: e.target.value
    });
  }
  render() {
    const items = this.state.toDoList.map(i => <li>{i}</li>); // 修改这一行
    return (
      <div>
        <textarea
          onChange={this.handleChange}
          value={this.state.userInput}
          style={textAreaStyles}
          placeholder='Separate Items With Commas'
        />
        <br />
        <button onClick={this.handleSubmit}>Create List</button>
        <h1>My "To Do" List:</h1>
        <ul>{items}</ul>
      </div>
    );
  }
}

技术点:使用Array.map()动态渲染元素。将存储在组件内部state中的toDoList数组一一遍历,并相应地动态呈现在li元素中。

给同级元素一个唯一的键属性

const frontEndFrameworks = [
  'React',
  'Angular',
  'Ember',
  'Knockout',
  'Backbone',
  'Vue'
];

function Frameworks() {
  const renderFrameworks = frontEndFrameworks.map(i => <li key={i}>{i}</li>); // 修改这一行
  return (
    <div>
      <h1>Popular Front End JavaScript Frameworks</h1>
      <ul>
        {renderFrameworks}
      </ul>
    </div>
  );
};

注意:键只需要在兄弟元素之间是唯一的,它们不需要在应用程序中是全局唯一的;最好不要用数组索引。

使用 Array.Filter() 动态过滤数组

如果有一个 users 数组,每个数组元素都有一个可以设置为 true 或 false 的 online 属性,可以这样只过滤那些在线的用户:

let onlineUsers = users.filter(user => user.online);

用 renderToString 在服务器上渲染 React

class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <div/>
  }
};

// 修改这行下面的代码
ReactDOMServer.renderToString(<App />);

这创造了更快的初始页面加载体验,因为渲染的 HTML 代码量要比整个应用程序的 JavaScript 代码小。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值