DataV+Echarts

1. 安装 vue3


也就是安装了一下vue3,但是 dataV 和 Echarts 的学习并没有使用vue的脚手架去创建一个项目。
原因有两点:

  1. dataV 目前对 vue3 的支持并不是很友好,主要还是基于 vue2 框架的一个组件库。
  2. 脚手架创建 vue 项目确实会使开发更加的有逻辑性,方便和快捷,也有着其特定的功能(下面会将关于 vue 开发的结构)。但是,首先,我不是一个前端工程师,我只需要将我想要展示的东西搞出来就好,更专业的事情应该交给更专业的人来做;再次,实在不想装一些我不经常用的东西(纯属个人强迫症)。

当然,你们如果想用 vue 脚手架来构建项目 完全可以,和导入 vue.js 来做开发的方法大致都是差不多的,只是 vue 项目有其自己的结构和写法,自行百度或者问 chatGPT。

1.1 关于node.js版本的升级

由于我是用的是Ubuntu20.04
Ubuntu 20.04的官方仓库中提供了一个相对较旧的Node.js版本,如果需要升级Node.js到最新版本,可以进行下面的操作
注意:
在升级Node.js之前,建议备份重要的项目文件和数据,以免升级过程中出现意外情况导致数据丢失

  1. 确认已安装curl和gnupg2工具,如果没有安装,可以使用以下命令安装:
sudo apt update
sudo apt install curl gnupg2
  1. 添加Node.js官方PPA(Personal Package Archive)软件源,并更新软件包列表:
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt update
# 这里使用的是Node.js 16.x版本
# 如果需要升级到18版本,可以将上述命令中的setup_16.x替换成setup_18.x
  1. 安装Node.js和npm:
sudo apt install nodejs
# 安装 nodejs 会自己附带npm的安装
  1. 验证Node.js和npm是否安装成功:
node -v
npm -v
# 如果输出了Node.js和npm的版本号,则说明安装成功

2. dataV


简单说就是 vue 的一个组件,对 vue 组件有了解的话,应该就会对 dataV 会有一个很好的理解,当然,肯定就会用啦!

2.1 vue 组件

官方文档链接

2.1.1 vue 组件的由来

前端开发中经常会遇到代码复用,比如一个京东购物网站的导航栏(顶部)在每一个页面都存在(也有不存在的,不要杠。。。),就可以理解为是一种代码复用的结果(当然,我也不知道京东用了什么技术,也不要抬杠,就是举个例子),就是通过复用导航栏的那一部分的代码,比如 htmlcssjs 等,来达到每个页面具有相同结构的目的。
然而有时代码复用,可能由于代码很长,致使阅读代码很困难等等,是一个又耗时又费力的操作,两种解决方案:

  1. cssjs 的模块化管理(主要是 js
  2. vue 组件化编程

这里可能涉及一个单页应用多页应用的概念,目前还不怎么理解

2.1.2 vue 组件

简单理解就是:
用来实现局部(特定)功能效果的代码集合

组件的组织

上面的图来自 vue 官方,简单理解就是:

  1. 其中根节点是一个Vue实例
  2. 其子节点就是一个个的组件
  3. 子节点之间存在父子关系,也就是说vue组件也存在父子关系

2.1.3 非单页面组件

非单页面组件:一个文件中可以包含有n个组件
单文件组件:一个文件中只包含有1个组件(这种通常在使用vue脚手架创建的vue项目中使用)

这里我们使用非单页面来创建组件,这个懂了,单文件组件就很简单了

几个注意点:

  1. 关于组件名:
    一个单词:
    第一种写法(全小写):test
    第二种写法(首字母大写):Test
    多个单词组成时:
    第一种写法(全小写):mytest
    第二种写法(kebab-case命名):my-test
    第三种写法(CamelCase命名):MyTest(需要Vue脚手架支持)
    注:可以使用 name 配置项指定组件在开发者工具中呈现的名字,一般在大项目中会使用
  2. 关于组件标签:
    第一种写法:<test> </test>
    第二种写法:<test/>
    注:不使用脚手架时,test/ 会导致后续组件不能渲染
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <!-- 引入 vue.js -->
    <script src="./js/vue@2.7.14.js"></script>

</head>

<body>
    <div id="root">

        <test></test>
        <!-- <test inline-template>
            <div>
                <p>姓名:{{name}}</p>
                <p>年龄:{{age}}</p>
            </div>
        </test> -->
    </div>





</body>
<script type="text/javascript">

    /*
    VueComponent:
        1. test组件的本质就是名为 VueComponent 的构造函数,即 test 组件是 VueComponent 的实例对象
        2. Vue官方给的构建组件的方式为:

            // 定义一个名为 button-counter 的新组件
            Vue.component('button-counter', {
                data: function () {
                    return {
                        count: 0
                    }
                },
                template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
            })

            <div id="components-demo">
            <button-counter></button-counter>
            </div>

    关于 this 的指向
        (1) 组件配置(也就是说VueComponent的实例对象)中的 this
            data函数、methods中的函数、watch中的函数、computed中的函数 它们的 this 均是【VueComponent实例对象】
        (2) new Vue(options)配置中:
            data函数、methods中的函数、watch中的函数、computed中的函数 它们的 this 均是【Vue实例对象】
    */


    // 注册、声明一个组件
    const test = Vue.extend({

        // 定义组件在Vue开发者工具中的显示名称
        // 但是在 html 中使用时 还是vue实例中注册的组件名称
        name: 'mytest',

        // 组件中的 html 模板
        template: `
            <div>
                <p>姓名:{{name}}</p>
                <p>年龄:{{age}}</p>
            </div>
        `,

        // data必须是一个函数
        // data: function () {}
        data() {
            return {
                name: ' xiaoming',
                age: 20
            }
        }
    })

    /*
    组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,
    例如 data、computed、watch、methods 以及生命周期钩子等。
    仅有的例外是像 el 这样根实例特有的选项。
    */

    // 全局注册
    // Vue.component('test', test)

    var vm = new Vue({
        el: '#root',

        // 注册组件 (局部注册)
        components: {

            // 组件名称: 声明的组件
            // html 文件中引用组件的方式就是 <组件名称></组件名称>
            // 一般情况下 组件名称和我们想绑定的组件名称是一样的
            test: test
            // xxx: test    可以更换 test 组件的名称
            // test         组件名称也可以不写,相当与 test: test
        }
    })
</script>

</html>

2.1.4 组件模板的引用(或者说写法)

2.1.5 组件的嵌套

注意:在组件被嵌套前一定是要先被创建好。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <!-- 引入 vue.js -->
    <script src="./js/vue@2.7.14.js"></script>

</head>

<body>
    <div id="root">

        <test></test>
    </div>
</body>

<script type="text/javascript">

    const test1 = Vue.extend({
        template: `
            <div>
                <p>姓名:{{name}}</p>
                <p>年龄:{{age}}</p>
            </div>
        `,
        data() {
            return {
                name: ' xiaohong',
                age: 20
            }
        }
    })

    // 注册、声明一个组件
    const test = Vue.extend({
        template: `
            <div>
                <p>姓名:{{name}}</p>
                <p>年龄:{{age}}</p>
                <test1></test1>
            </div>
        `,
        data() {
            return {
                name: ' xiaoming',
                age: 20
            }
        },

        // A 嵌套 B 就在 A 的组件配置中注册 B
        // 并且在 A 的 template 中使用 B
        components: {
            test1
        }
    })

    var vm = new Vue({
        el: '#root',

        // 注册组件 (局部注册)
        components: {
            test
        }
    })
</script>

</html>

2.1.6 单文件组件

单文件组件是由 .vue 类型文件,他不是 js 文件 浏览器没办法去解析这个文件。
两种方法:

  1. Vue CLI,基于 webpack
  2. Vite 前端工具链

(1)文件结构

# 构建 vue 实例
main.js
# 组件的 leader
App.vue
# 单个组件文件
test1.vue
test2.vue
# html 文件作为容器
index.html
......

(2)文件中的内容

下面只是简单表明一下 单文件组件怎么写,没有创建 vue 工程 代码是跑不成功的

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root">
        <!-- 使用App组件 -->
        <App></App>
    </div>

    <script src="text/javascript" src="./main.js"></script>
</body>

</html>
<!-- --------------------------------------------------------------- -->
<!-- 组件1.vue -->

<template>
    <div class="demo1">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{age}}</h2>
        <button @click="showName">点我显示姓名</button>
    </div>

</template>

<script>
    // 暴露
    // 有三种暴露方式,下面的额是默认方式
    // 不同的暴露方式导入方式也有所不同
    export default ({
        name: 'test1',
        data() {
            return {
                name: ' xiaoming',
                age: 20
            }
        },
        methods: {
            showName() {
                alert(this.name)
            }
        }
    })
</script>

<style>
    .demo {
        background-color: blueviolet;
    }
</style>
<!-- --------------------------------------------------------------- -->
<!-- App.vue -->

<template>
    <div class="demo1">
    <test1></test1>
    </div>

</template>

<script>
    import test1 from './test1.vue'

    export default ({
        name: 'App',
        components: {
            test1
        }
    })
</script>
<!-- --------------------------------------------------------------- -->
<!-- main.js -->

import App from './App.vue'
 
new Vue ({
    el:'#root',
    components:{App}
})

2.2 Vue 大屏数据展示组件库 dataV

2.2.1 CSS中的flex布局

大屏可视化的一个重点就是 页面布局 ,此次基于dataV的大屏可视化项目就是采用flex对页面进行的整体布局
布局的传统解决方案,基于盒状模型,依赖display属性+position属性+float属性。
2009年,W3C提出了一种新的方案—flex布局,可以简便、完整、响应式地实现各种页面布局。

flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

  1. 任何一个容器都可以指定为flex布局:display: flex;
  2. 行内元素也可以使用Flex布局:display: inline-flex;

参考文档

2.2.2 flex容器的6个属性

(1) flex-direction

.box {
    flex-direction: row | row-reverse | column | column-reverse;
}

/* 它可能有4个值。*/
/* row(默认值):主轴为水平方向,起点在左端。 */
/* row-reverse:主轴为水平方向,起点在右端。 */
/* column:主轴为垂直方向,起点在上沿。 */
/* column-reverse:主轴为垂直方向,起点在下沿。 */

(2) flex-wrap

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

.box {
    flex-wrap: nowrap | wrap | wrap-reverse;
}

/* 它可能取三个值。 */
/* (1)nowrap(默认):不换行。 */
/* (2)wrap:换行,第一行在上方。 */
/* (3)wrap-reverse:换行,第一行在下方。 */

(3) flex-flow

.box {
    flex-flow: <flex-direction> <flex-wrap>;
}

/* flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。 */

(4) justify-content

justify-content属性定义了项目在主轴上的对齐方式。

.box {
    justify-content: flex-start | flex-end | center | space-between | space-around;
}

/* 它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。 */
/* flex-start(默认值):左对齐 */
/* flex-end:右对齐 */
/* center: 居中 */
/* space-between:两端对齐,项目之间的间隔都相等。 */
/* space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 */

(5) align-items

align-items属性定义项目在交叉轴上如何对齐。

.box {
    align-items: flex-start | flex-end | center | baseline | stretch;
}

/* 它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。 */
/* flex-start:交叉轴的起点对齐。 */
/* flex-end:交叉轴的终点对齐。 */
/* center:交叉轴的中点对齐。 */
/* baseline: 项目的第一行文字的基线对齐。 */
/* stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。 */

(6) align-content

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

.box {
    align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}


/* 该属性可能取6个值。 */
/* flex-start:与交叉轴的起点对齐。 */
/* flex-end:与交叉轴的终点对齐。 */
/* center:与交叉轴的中点对齐。 */
/* space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 */
/* space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 */
/* stretch(默认值):轴线占满整个交叉轴。 */

2.2.3 flex项目上的6个属性

也就是说在具体应用时,有下面6个属性
orderflex-growflex-shrinkflex-basisflexalign-self

.item {
    order: <integer>;
}

/* order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。 */


.item {
    flex-grow: <number>; /* default 0 */
}

  /* flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 */
  /* 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。 */
  /* 如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。 */

.item {
    flex-shrink: <number>; /* default 1 */
}

/* flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。 */
/* 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。 */
/* 如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。 */
/* 负值对该属性无效。 */

.item {
    flex-basis: <length> | auto; /* default auto */
}

/* flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。 */
/* 浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。 */
/* 它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。 */

.item {
    flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

/* flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。 */
/* 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。 */
/* 建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。 */

.item {
    align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

/* align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。 */
/* 默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。 */
/* 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。 */

2.2.4 flex布局在本项目中的应用

注意点:

  1. 使用百分比的形式设置特定参数的值
  2. flex容器的无法实现多层嵌套,要实现多层嵌套需要设置盒子模型为flex容器(不太好理解,可以看下面 class="middle" 中的代码)
  3. dataV 边框样式官方参考文档
<!-- .top {
	width: 100%;
	height: 6%;
	margin-top: 10px;
	display: flex;
	/* 两端对齐 */
	justify-content: space-between;
	} -->
<div id="root">

    <dv-full-screen-container>

        <div class="top">
            <!-- 
                style="flex:0 1 30%"
                这是一个CSS的样式属性,表示一个元素的伸缩性,具体解释如下:
                flex-grow: 0:该元素不会被拉伸。
                flex-shrink: 1:该元素可以被收缩。
                flex-basis: 30%:该元素的初始大小为其父容器的30%。

                综合起来,这个样式属性的作用是,将该元素的初始大小设置为其父容器宽度的30%,
                同时如果该元素在布局时需要被收缩,它会尽可能地收缩以适应父容器的大小。
                -->
            <div style="flex:0 1 30%">
                <dv-decoration-8 style="width:100%;height:50%;" />
            </div>
            <!-- 
                margin(外边距)是指元素周围的空白区域,用于控制元素与其他元素之间的距离。

                margin的使用方式如下:
                margin: 上 右 下 左;
                上、右、下、左指定了元素的四个方向上的外边距,可以用长度值(如px、em等)或百分比来指定。

                设置元素的上下外边距和左右外边距:
                margin: 上下 左右;

                分别设置元素的四个方向上的外边距:
                margin-top: 上;
                margin-right: 右;
                margin-bottom: 下;
                margin-left: 左;
            -->
            <div style="flex:0 1 40%; margin-top: 20px;">
                <dv-decoration-5 style="width:100%;height:100%;" />
            </div>

            <div style="flex:0 1 30%">
                <dv-decoration-8 :reverse="true" style="width:100%;height:50%;" />
            </div>

            <div class="center-title">
                额河数据可视化平台
            </div>

        </div>

        <!-- .middle {
            width: 100%;
            height: 90%;
            margin-top: 10px;
            display: flex;
            flex-direction: row;
            /* 居中对齐 */
            justify-content: space-between;
        } -->
        <div class="middle">

            <div style="flex:0 1 25%;">
                <dv-border-box-3 style="width: 100%; height: 100%;">
                    dv-border-box-3
                </dv-border-box-3>
            </div>

            <div style="flex:0 1 75%; display: flex; flex-direction: column;">

                <div style="flex:0 1 65%; display: flex; flex-direction: row;">

                    <div style="flex:0 1 65%;">
                        <dv-border-box-3 style="width: 100%; height: 100%;">
                            dv-border-box-3
                        </dv-border-box-3>
                    </div>

                    <div style="flex:0 1 35%; display: flex; flex-direction: column;">
                        <div style="flex:0 1 50%">
                            <dv-border-box-3 style="width: 100%; height: 100%;">
                                dv-border-box-3
                            </dv-border-box-3>
                        </div>
                        <div style="flex:0 1 50%">
                            <dv-border-box-4 :reverse="true" style="width: 100%; height: 100%;">
                                dv-border-box-4
                            </dv-border-box-4>
                        </div>
                    </div>

                </div>

                <div style="flex:0 1 35%;">
                    <dv-border-box-4 style="width: 100%; height: 100%;">
                        dv-border-box-4
                    </dv-border-box-4>
                </div>

            </div>
        </div>

    </dv-full-screen-container>

</div>

下面是布局后的效果图:

在这里插入图片描述

dataV中的飞线图

原理与相关说明:

  1. 背景是一张图片,飞线的起点和终点是图片中的相对坐标(默认)
  2. 组件提供了dev模式 ,可以帮助快速确定飞线点位置
  3. 官方参考文档

dataV中的图表

官方:图表组件基于 Charts 封装,其也提供了许多常用的图表样式,用法和 echarts 差不多,但是在访问其js文件时,出现了404错误。。。所以还是使用 echarts 吧
官方链接

3. dataV结合Echarts的使用

echarts官网
echarts官方文档
echarts的js文件

3.1 vue项目中或者TS环境下的使用

由于本次项目并没有在此环境下进行开发,所以不做介绍,官方文档 写的很清楚。

3.2 在原生js环境下的使用

需要注意的一点就是,echarts 的 js 需要在 vue 实例构建完成之后,也就是说,其要放在 vue 实例构建 之后,否则可能会导致渲染失败。

<!-- 这里的尺寸之所以采用百分比的形式来表示
	是因为其在一个 flex 容器下设置的 echarts 图表
	可以使用 px -->
<div id="main" style="width: 100%;height:100%;"></div>
<div id="main1" style="width: 50%;height:100%;"></div>

<script type="text/javascript">

    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'), 'dark');
    var myChart1 = echarts.init(document.getElementById('main1'), 'dark');

    // 指定图表的配置项和数据
    var option = {
        backgroundColor: '',
        title: {
            text: 'ECharts 入门示例'
        },
        tooltip: {},
        legend: {
            data: ['销量']
        },
        xAxis: {
            data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
            {
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20],
            }
        ]
    };
    var option1 = {
        backgroundColor: '',
        tooltip: {
            trigger: 'item'
        },
        legend: {
            top: '5%',
            left: 'center'
        },
        series: [
            {
                name: 'Access From',
                type: 'pie',
                radius: ['40%', '70%'],
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                emphasis: {
                    label: {
                        show: true,
                        fontSize: 40,
                        fontWeight: 'bold'
                    }
                },
                labelLine: {
                    show: false
                },
                data: [
                    { value: 1048, name: 'Search Engine' },
                    { value: 735, name: 'Direct' },
                    { value: 580, name: 'Email' },
                    { value: 484, name: 'Union Ads' },
                    { value: 300, name: 'Video Ads' }
                ]
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
    myChart1.setOption(option1);
    
</script>

效果如下图黄色圈起来的部分

在这里插入图片描述

3.3 使用vue非单页面组件的方式使用

<!-- 一般情况下 应该给组件一个盒子或者容器 -->
<div style="width: 25%;height:90%;">
	<test></test>
</div>

<script>
const test = Vue.extend({
    template: `
    <div id="main3" style="width: 100%;height:100%;"></div>
    `,

    // data 应以函数的形式返回值
    data() {
        return {
            option: {
                backgroundColor: '',
                title: {
                    text: 'Nightingale Chart',
                    subtext: 'Fake Data',
                    left: 'center'
                },
                series: [
                    {
                        name: 'Area Mode',
                        type: 'pie',
                        radius: [20, 140],
                        center: ['50%', '50%'],
                        roseType: 'area',
                        itemStyle: {
                            borderRadius: 5
                        },
                        data: [
                            { value: 30, name: 'rose 1' },
                            { value: 28, name: 'rose 2' },
                            { value: 26, name: 'rose 3' },
                            { value: 24, name: 'rose 4' },
                            { value: 22, name: 'rose 5' },
                            { value: 20, name: 'rose 6' },
                            { value: 18, name: 'rose 7' },
                            { value: 16, name: 'rose 8' }
                        ]
                    }
                ]
            }
        }
    },
    mounted() {
        // 在生命周期中挂载图表
        var myChart = echarts.init(document.getElementById('main3'), 'dark');
        myChart.setOption(this.option)
    }
})

var vm = new Vue({
    el: '#root',
    // 注册组件
    components: {
        test,
    }
})
</script>

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值