ReactNative进阶(七):导航组件 react-navigation_react native导航栏组件

react和vue的比较

相同
1)vitual dom
2)组件化
3)props,单一数据流

不同点
1)react是jsx和模板;(jsx可以进行更多的js逻辑和操作)
2)状态管理(react)
3)对象属性(vue)
4)vue:view——medol之间双向绑定
5)vue:组件之间的通信(props,callback,emit)

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

3、 DrawerNavigator: 抽屉效果,侧边滑出;

三、StackNavigator 导航栏

StackNavigator(RouteConfigs, StackNavigatorConfig)

StackNavigator 组件采用堆栈式的页面导航来实现各个界面跳转。如果想要使用StackNavigator,一定要先注册导航

其中,createStackNavigator用于配置栈管理的页面。在createStackNavigator模式下,为了方便对页面进行统一管理,首先新建一个RouterConfig.js文件,并使用createStackNavigator注册页面。对于应用的初始页面还需要使用initialRouteName进行申明。同时,导航器栈还需要使用createAppContainer函数进行包裹。示例代码如下:

RouterConfig.js文件

import {createAppContainer,createStackNavigator} from 'react-navigation';

import MainPage from './MainPage'
import DetailPage from "./DetailPage";

const AppNavigator = createStackNavigator({
    MainPage: MainPage,       
    DetailPage:DetailPage
},{
   initialRouteName: "MainPage",
},
);
export default createAppContainer(AppNavigator);

接下来,在入口文件中以组件的方式引入StackNavigatorPage.js文件即可。例如:

import StackNavigatorPage from './src/StackNavigatorPage'

export default class App extends Component<Props> {
  render() {
    return (
      <StackNavigatorPage/>
    );
  }
}

然后,就可以进行导航配置了。

const Navigator = StackNavigator(
    {
        Tab: { screen: Tab },
        Web: { screen: WebScene },
        GroupPurchase: { screen: GroupPurchaseScene },
    },
    {
        navigationOptions: {
            // headerStyle: { backgroundColor: color.theme }
            headerBackTitle: null,
            headerTintColor: '#333333',
            showIcon: true,
        },
    }
);

这里给导航器配置了三个界面,如果需要更多界面,可以在之后进行添加。主要有一个用于主界面之间能够切换的Tab界面和其他两个能够展示数据的界面。

3.1 StackNavigatorConfig 导航器配置
  • initialRouteName - 导航器组件中初始显示页面的路由名称,如果不设置,则默认第一个路由页面为初始显示页面;
  • initialRouteParams - 给初始路由的参数,在初始显示的页面中可以通过this.props.navigation.state.params 来获取;
  • navigationOptions -路由页面的配置选项,它会被 RouteConfigs 参数中navigationOptions 的对应属性覆盖;
  • paths -路由中设置的路径覆盖映射配置;
  • mode - 页面跳转方式,有 cardmodal 两种,默认为 card
    1. card - 原生系统默认的的跳转,左右互换;
    2. modal - 只针对iOS平台,模态跳转,上下切换;
  • headerMode - 页面跳转时,头部的动画模式,有 float 、 screen 、 none 三种:
    1. float -渐变,类似iOS的原生效果,无透明;
    2. screen - 标题与屏幕一起淡入淡出,如微信一样;
    3. none - 没有动画;
  • cardStyle -为各个页面设置统一的样式,比如背景色,字体大小等;
  • transitionConfig - 配置页面跳转的动画,覆盖默认的动画效果;
  • onTransitionStart - 页面跳转动画即将开始时调用;
  • onTransitionEnd - 页面跳转动画一旦完成会马上调用;

代码示例:

const StackNavigatorConfig = {
    initialRouteName: 'Home',
    initialRouteParams: {initPara: '初始页面参数'},
    navigationOptions: {
        title: '标题',
        headerTitleStyle: {fontSize: 18, color: '#666666'},
        headerStyle: {height: 48, backgroundColor: '#'},
    },
    paths: 'page/main',
    mode: 'card',
    headerMode: 'screen',
    cardStyle: {backgroundColor: "#ffffff"},
    transitionConfig: (() => ({
        screenInterpolator: CardStackStyleInterpolator.forHorizontal,
    })),
    onTransitionStart: (() => {
        console.log('页面跳转动画开始');
    }),
    onTransitionEnd: (() => {
        console.log('页面跳转动画结束');
    }),
};

3.2 navigationOptions 为对应路由页面的配置选项
  • title - 可以作为头部标题 headerTitle ,或者Tab标题 tabBarLabel;
  • header -自定义的头部组件,使用该属性后系统的头部组件会消失,如果想在页面中自定义,可以设置为null,这样就不会出现页面中留有一个高度为64 navigationBar的高度;
  • headerTitle - 头部的标题,即页面的标题 headerBackTitle - 返回标题,默认为 title;
  • headerTruncatedBackTitle - 返回标题不能显示时(比如返回标题太长了)显示此标题,默认为 “Back”;
  • headerRight - 头部右边组件;
  • headerLeft - 头部左边组件;
  • headerStyle - 头部组件的样式;
  • headerTitleStyle - 头部标题的样式;
  • headerBackTitleStyle - 头部返回标题的样式;
  • headerTintColor - 头部颜色 headerPressColorAndroid - Android 5.0以上MD风格的波纹颜色 ;
  • gesturesEnabled - 否能侧滑返回, iOS 默认 trueAndroid 默认 false;

使用示例

// 注册导航
const Navs = StackNavigator({
    Home: { screen: Tabs },
    HomeTwo: {
        screen: HomeTwo,  // 必须, 其他都是非必须
        path:'app/homeTwo', // 使用url导航时用到, 如 web app 和 Deep Linking
        navigationOptions: {}  // 此处参数设置会覆盖组件内的`static navigationOptions`设置. 具体参数详见下文;
    },
    HomeThree: { screen: HomeThree },
    HomeFour: { screen: HomeFour }
  }, {
    initialRouteName: 'Home', // 默认显示界面
    navigationOptions: {  // 屏幕导航的默认选项, 也可以在组件内用 static navigationOptions 设置(会覆盖此处的设置)
        header: {  // 导航栏相关设置项
            backTitle: '返回',  // 左上角返回键文字
            style: {
                backgroundColor: '#fff'
            },
            titleStyle: {
                color: 'green'
            }
        },
        cardStack: {
            gesturesEnabled: true
        }
    }, 
    mode: 'card',  // 页面切换模式, 左右是card(相当于iOS中的push效果), 上下是modal(相当于iOS中的modal效果)
    headerMode: 'screen', // 导航栏的显示模式, screen: 有渐变透明效果, float: 无透明效果, none: 隐藏导航栏
    onTransitionStart: ()=>{ console.log('导航栏切换开始'); },  // 回调
    onTransitionEnd: ()=>{ console.log('导航栏切换结束'); }  // 回调
});

当然页面配置选项 navigationOptions 还可以在对应页面中去静态配置。

    // 配置页面导航选项
    static navigationOptions = ({navigation}) => ({
        title: 'HOME',
        titleStyle: {color: '#ff00ff'},
        headerStyle:{backgroundColor:'#000000'}
    });

    render() {
        return (
            <View></View>
        )
    };
}

在页面采用静态方式配置 navigationOptions 中的属性,会覆盖 StackNavigator 构造函数中两个参数 RouteConfigsStackNavigatorConfig 配置的 navigationOptions 里面的对应属性。

navigationOptions 中属性的优先级是:

页面中静态配置 > RouteConfigs > StackNavigatorConfig

至此,就可以在组件中直接使用该配置了,当然我们也可以像文章开头提过的那样使用:

const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig);

export default class Main extends Component {
    render() {
        return (
            <Navigator/>
        )
    };
}

至此,我们已经配置好导航器和对应的路由页面,但是我们还需要navigation才能实现页面的跳转。

3.3 navigation 控制页面跳转

在导航器中的每一个页面,都有 navigation 属性,该属性有以下几个属性/方法,可以在组件下console.log(this.props)查看。

  • navigate - 跳转到其他页面;
  • state - 当前页面导航器的状态;
  • setParams - 更改路由的参数;
  • goBack - 返回;
  • dispatch - 发送一个action

navigate

this.props.navigation.navigate(‘Two’, { name: ‘two’ }) // push下一个页面

  • routeName: 注册过的目标路由名称;
  • params: 传递的参数,传递到下一级界面 ;
  • action:如果该界面是一个navigator的话,将运行这个sub-action;

state
state 里面包含有传递过来的参数 paramskey 、路由名称 routeName

  • routeName: 路由名;
  • key: 路由身份标识;
  • params: 参数;

setParams
this.props.navigation.setParams
该方法允许界面更改router中的参数,可以用来动态更改导航栏的内容。比如可以用来更新头部的按钮或者标题。

goBack
返回上一页,可以不传参数,也可以传参数,还可以传 null

this.props.navigation.goBack();       // 回退到上一个页面
this.props.navigation.goBack(null);   // 回退到任意一个页面
this.props.navigation.goBack('Home'); // 回退到Home页面

dispatch

this.props.navigation.dispatch

可以dispatch一些action,主要支持的action有:

1. Navigate

import { NavigationActions } from 'react-navigation'

  const navigationAction = NavigationActions.navigate({
    routeName: 'Profile',
    params: {},

    // navigate can have a nested navigate action that will be run inside the child router
    action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
  })
  this.props.navigation.dispatch(navigationAction)

2. Reset
Reset方法会清除原来的路由记录,添加上新设置的路由信息, 可以指定多个actionindex是指定默认显示的那个路由页面, 注意不要越界!

import { NavigationActions } from 'react-navigation'

  const resetAction = NavigationActions.reset({
    index: 0,
    actions: [
      NavigationActions.navigate({ routeName: 'Profile'}),
      NavigationActions.navigate({ routeName: 'Two'})
    ]
  })
  this.props.navigation.dispatch(resetAction)

SetParams
为指定的router更新参数,该参数必须是已经存在于routerparam中。

  import { NavigationActions } from 'react-navigation'

  const setParamsAction = NavigationActions.setParams({
    params: {}, // these are the new params that will be merged into the existing route params
    // The key of the route that should get the new params
    key: 'screen-123',
  })
  this.props.navigation.dispatch(setParamsAction)

3.4 页面跳转,传值,回调传参

跳转,传值

  const {navigate} = this.props.navigation;
  <TouchableHighlight onPress={()=>{
       navigate('PlanDetail',{name:'leslie',id:100});
  }}>

  // 返回上一页
  this.props.navigation.goBack();

在下一界面接收参数
通过 this.props.navigation.state.params 接收参数

export default class Home1 extends Component {
      static navigationOptions = {
          // title 可以这样设置成一个函数, state 会自动传过来
          title: ({state}) => `${state.params.name}`,
      };

      componentDidMount() {
          const {params} = this.props.navigation.state;
          const id = params.id;
      }
    }

3.5 回调传参

当前界面进行跳转

navigate('Detail',{
   // 跳转的时候携带一个参数去下个页面
   callback: (data)=>{
         console.log(data); // 打印值为:'回调参数'
     }
  });

下一界面在返回之前传参

const {navigate,goBack,state} = this.props.navigation;
// 在第二个页面,在goBack之前,将上个页面的方法取到,并回传参数,这样回传的参数会重走render方法
state.params.callback('回调参数');
goBack();

四、TabNavigator 即 Tab 选项卡

TabNavigator(RouteConfigs, TabNavigatorConfig)

apiStackNavigator 类似,参数 RouteConfigs 是路由配置,参数 TabNavigatorConfigTab选项卡配置。

如果要实现底部选项卡切换功能,可以直接使用react-navigation提供的createBottomTabNavigator接口,并且此导航器需要使用createAppContainer函数包裹后才能作为React组件被正常调用。例如:

import React, {PureComponent} from 'react';
import {StyleSheet, Image} from 'react-native';
import {createAppContainer, createBottomTabNavigator} from 'react-navigation'

import Home from './tab/HomePage'   
import Mine from './tab/MinePage'

const BottomTabNavigator = createBottomTabNavigator(
    {
        Home: {
            screen: Home,
            navigationOptions: () => ({
                tabBarLabel: '首页',
                tabBarIcon:({focused})=>{
                    if(focused){
                        return(
                          <Image/>   //选中的图片
                        )
                    }else{
                        return(
                           <Image/>   //默认图片 
  )
                    }
                }
            }),
        },
        Mine: {
            screen: Mine,
            navigationOptions: () => ({
                tabBarLabel: '我的',
                tabBarIcon:({focused})=>{
                    …
                }
            })
        }
    }, {  //默认参数设置
        initialRouteName: 'Home',
        tabBarPosition: 'bottom',
        showIcon: true,
        showLabel: true,
        pressOpacity: 0.8,
        tabBarOptions: {
            activeTintColor: 'green',
            style: {
                backgroundColor: '#fff',
            },
        }
    }
);

const AppContainer = createAppContainer(BottomTabNavigator);

export default class TabBottomNavigatorPage extends PureComponent {
    render() {
        return (
            <AppContainer/>
        );
    }
}

4.1 RouteConfigs 路由配置

路由配置和 StackNavigator 中是一样的,配置路由以及对应的 screen 页面,navigationOptions 为对应路由页面的配置选项:

  • title - Tab标题,可用作headerTitletabBarLabel 回退标题;
  • tabBarVisible -Tab是否可见,没有设置的话默认为 true;
  • tabBarIcon - Tabicon组件,可以根据 {focused:boolean, tintColor: string} 方法来返回一个icon组件;
  • tabBarLabel -Tab中显示的标题字符串或者组件,也可以根据 { focused: boolean, tintColor: string };方法返回一个组件;

代码示例:

Mine: {
   screen: MineScene,
   navigationOptions: ({ navigation }) => ({
       tabBarLabel: '我的',
       tabBarIcon: ({ focused, tintColor }) => (
           <TabBarItem
               tintColor={tintColor}
               focused={focused}
               normalImage={require('./img/tabbar/pfb\_tabbar\_mine@2x.png')}
               selectedImage={require('./img/tabbar/pfb\_tabbar\_mine\_selected@2x.png')}
           />
       )
   }),
},

TabBarItem自定义组件

class TabBarItem extends PureComponent {
    render() {
        let selectedImage = this.props.selectedImage ? this.props.selectedImage : this.props.normalImage
        return (
            <Image
                source={this.props.focused
                    ? selectedImage
                    : this.props.normalImage}
                style={{ tintColor: this.props.tintColor, width: 25, height: 25 }}
            />
        );
    }
}

五、TabNavigatorConfig Tab选项卡配置

  • tabBarComponent - Tab选项卡组件,有 TabBarBottomTabBarTop 两个值,在iOS中默认为 TabBarBottom ,在Android中默认为 TabBarTop

    1. TabBarTop - 在页面顶部;
    2. TabBarBottom - 在页面底部;
  • tabBarPosition - Tab选项卡的位置,有topbottom两个值

    1. top:上面
    2. bottom:下面
  • swipeEnabled - 是否可以滑动切换Tab选项卡;

  • animationEnabled - 点击Tab选项卡切换界面是否需要动画;

  • lazy - 是否懒加载页面;

  • initialRouteName - 初始显示的Tab对应的页面路由名称;

  • order - 用路由名称数组来表示Tab选项卡的顺序,默认为路由配置顺序;

  • paths - 路径配置;

  • backBehavior - android点击返回键时的处理,有 initialRoutenone 两个值:

    1. initailRoute - 返回初始界面;
    2. none - 退出;
  • tabBarOptions - Tab配置属性,用在TabBarTopTabBarBottom时有些属性不一致:

用于 TabBarTop 时:

  • activeTintColor - 选中的文字颜色;
  • inactiveTintColor - 未选中的文字颜色;
  • showIcon -是否显示图标,默认显示;
  • showLabel - 是否显示标签,默认显示;
  • upperCaseLabel - 是否使用大写字母,默认使用;
  • pressColor - android 5.0以上的MD风格波纹颜色;
  • pressOpacity - android5.0以下或者iOS按下的透明度;
  • scrollEnabled - 是否可以滚动;
  • tabStyle - 单个Tab的样式;
  • indicatorStyle - 指示器的样式;
  • labelStyle - 标签的样式;
  • iconStyle - icon的样式;
  • style -整个TabBar的样式;

用于 TabBarBottom 时:

  • activeTintColor - 选中Tab的文字颜色;
  • inactiveTintColor - 未选中Tab的的文字颜色;
  • activeBackgroundColor - 选中Tab的背景颜色;
  • inactiveBackgroundColor -未选中Tab的背景颜色;
  • showLabel - 是否显示标题,默认显示;
  • style - 整个TabBar的样式;
  • labelStyle -标签的样式;
  • tabStyle - 单个Tab的样式;

使用底部选项卡:

import React, {Component} from 'react';
import {StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
import TabBarItem from "./index18/TabBarItem";
export default class MainComponent extends Component {
    render() {
        return (
            <Navigator/>
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: '首页',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    tintColor={tintColor}
                    focused={focused}
                    normalImage={require('./img/tabbar/pfb\_tabbar\_homepage\_2x.png')}
                    selectedImage={require('./img/tabbar/pfb\_tabbar\_homepage\_selected\_2x.png')}
                />
            ),
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: '附近',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    tintColor={tintColor}
                    focused={focused}
                    normalImage={require('./img/tabbar/pfb\_tabbar\_merchant\_2x.png')}
                    selectedImage={require('./img/tabbar/pfb\_tabbar\_merchant\_selected\_2x.png')}
                />
            ),
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: '我的',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    tintColor={tintColor}
                    focused={focused}
                    normalImage={require('./img/tabbar/pfb\_tabbar\_mine\_2x.png')}
                    selectedImage={require('./img/tabbar/pfb\_tabbar\_mine\_selected\_2x.png')}
                />
            ),
        },
    }
};
const TabNavigatorConfigs = {
    initialRouteName: 'Home',
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    lazy: true,
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
    Tab: {
        screen: Tab,
    }
};
const StackNavigatorConfigs = {
    initialRouteName: 'Tab',
    navigationOptions: {
        title: '标题',
        headerStyle: {backgroundColor: '#5da8ff'},
        headerTitleStyle: {color: '#333333'},
    }
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

使用顶部选项卡:

import React, {Component} from "react";
import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
export default class MainComponent extends Component {
    render() {
        return (
            <Navigator/>
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: '首页',
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: '附近',
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: '我的',
        },
    }
#### 算法刷题

大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

![](https://img-blog.csdnimg.cn/img_convert/c582a01373152bb4cd38bc6ad5cc8027.png)



**写在最后**

**最后,对所以做Java的朋友提几点建议,也是我的个人心得:**

1.  疯狂编程

2.  学习效果可视化

3.  写博客
4.  阅读优秀代码
5.  心态调整



 {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: '首页',
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: '附近',
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: '我的',
        },
    }
#### 算法刷题

大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

![](https://img-blog.csdnimg.cn/img_convert/c582a01373152bb4cd38bc6ad5cc8027.png)



**写在最后**

**最后,对所以做Java的朋友提几点建议,也是我的个人心得:**

1.  疯狂编程

2.  学习效果可视化

3.  写博客
4.  阅读优秀代码
5.  心态调整



  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Native 提供了一种方便的方式来创建底部导航栏。你可以使用第三方库,比如 `react-navigation` 或 `react-native-navigation`,来实现底部导航。 下面是使用 `react-navigation` 库创建底部导航的简单示例: 1. 首先,确保你已经安装了 `react-navigation` 库: ``` npm install @react-navigation/native ``` 2. 创建一个底部导航组件: ```jsx import React from 'react'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { NavigationContainer } from '@react-navigation/native'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; import { faHome, faUser } from '@fortawesome/free-solid-svg-icons'; const Tab = createBottomTabNavigator(); const BottomTabNavigator = () => { return ( <NavigationContainer> <Tab.Navigator> <Tab.Screen name="Home" component={HomeScreen} options={{ tabBarIcon: ({ color, size }) => ( <FontAwesomeIcon icon={faHome} color={color} size={size} /> ), }} /> <Tab.Screen name="Profile" component={ProfileScreen} options={{ tabBarIcon: ({ color, size }) => ( <FontAwesomeIcon icon={faUser} color={color} size={size} /> ), }} /> </Tab.Navigator> </NavigationContainer> ); }; export default BottomTabNavigator; ``` 在上面的示例中,我们创建了一个包含两个屏幕(Home 和 Profile)的底部导航栏。我们使用了 `@fortawesome/react-native-fontawesome` 库来渲染图标,你也可以选择其他的图标库。 3. 创建 HomeScreen 和 ProfileScreen 组件,并实现它们的功能。 4. 在入口文件中使用底部导航组件: ```jsx import React from 'react'; import BottomTabNavigator from './BottomTabNavigator'; const App = () => { return <BottomTabNavigator />; }; export default App; ``` 这样,你就可以在 React Native 应用中使用底部导航栏了。当然,还有其他一些配置和功能可以使用,请参考 `react-navigation` 的文档以获取更多信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值