如何在VUE项目中使用前端数据库WebSQL

【Vue+Mysql实现前端对接数据库】 Vite + Vue3 工程化环境下,需要在 package.json 中配置。注意:Node 14+ 版本支持 CommonJS 和 ESM 两种规范。当然你也可以使用 CommonJS 规范通过。导入模块,这样项目中就存在两种规范的写法了。其它 api 文件配置参考 login.js。,且后端文件后缀需要由。 阅读详情

一、应用场景:最近个人接到一个项目,其中要求APP在非联网状态下使用,而且每个用户都可以自由操作数据,由于这种特殊性,考虑到用户数量较少且数据量较大,所以最终选择使用websql数据库来实现大量数据的存储。

**WebSQL是前端的一个独立模块,是web存储方式的一种(见下图,F12打开控制台可以看到)。

二、VUE中引入并使用

1、环境搭建,初始化项目(此条不做赘述,相关操作可自行搜索)

2、在src目录下新建WebSql文件夹,并创建WebSql.js,用于引入数据库相关操作

①在main.js中引入websql模块

 ②在WebSql.js中定义数据库

 

代码如下:

import Vue from 'vue'

const WebSql=function(){
    if(window.openDatabase){
        //openDatabase('数据库名称','版本','数据库描述','数据库大小')
        var db = openDatabase('TC','1.0','taicang',200*1024*1024);
       
        Vue.prototype.$db=db;
        
        if(!db){
            console.log("数据库创建失败!");
        }else{
            console.log('本地数据库创建成功!');
        }
    }else{
        console.log('不支持本地存储!');
    }
};
export default WebSql;

③创建表结构(此处做一个简单的demo,以三级联动为例),代码和效果如下

  //关联本地数据库
          this.$db.transaction(function(tx){
          //创建城镇、村落、组别三张表结构
            tx.executeSql('CREATE TABLE IF NOT EXISTS City (CityID unique  primary key , Name)');
            tx.executeSql('CREATE TABLE IF NOT EXISTS County (CountyID unique  primary key ,CityID, Name)');
            tx.executeSql('CREATE TABLE IF NOT EXISTS GroupList (GroupID unique primary key ,CountryID, Name,IsChoose)');
            
            //如果表中数据为空,则插入数据
            tx.executeSql('SELECT COUNT(*) AS NUM FROM City',[],function(tx,mes){
              if(mes.rows[0].NUM==0){
                console.log("插入城镇数据");
                tx.executeSql("insert into City(CityID,Name)values(1,'城厢镇')");
                tx.executeSql("insert into City(CityID,Name)values(2,'浮桥镇')");
                tx.executeSql("insert into City(CityID,Name)values(3,'璜泾镇')");
                tx.executeSql("insert into City(CityID,Name)values(4,'科教新城')");
                tx.executeSql("insert into City(CityID,Name)values(5,'浏河镇')");
                tx.executeSql("insert into City(CityID,Name)values(6,'娄东街道')");
                tx.executeSql("insert into City(CityID,Name)values(7,'沙溪镇')");
                tx.executeSql("insert into City(CityID,Name)values(8,'双凤镇')");
              }
            },function(tx,err){
              console.log(err);
            });
            tx.executeSql('SELECT COUNT(*) AS NUM FROM County',[],function(tx,mes){
              console.log(mes.rows[0].NUM);
              if(mes.rows[0].NUM==0){
                console.log("插入村落数据");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(1,1,'永丰村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(2,1,'胜泾村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(3,1,'万丰村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(4,1,'电站村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(5,1,'东林村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(6,1,'伟阳社区')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(7,1,'新农村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(8,1,'太丰社区')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(9,2,'茜泾村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(10,2,'马北村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(11,2,'新邵村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(12,2,'牌楼社区')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(13,2,'丁泾村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(14,2,'七丫村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(15,2,'九曲社区')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(16,2,'绿化村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(17,2,'时思村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(18,2,'时思社区')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(19,2,'浪港村')");
                tx.executeSql("insert into County(CountyID,CityID,Name)values(20,2,'老闸社区')");
              }
            },function(tx,err){
              console.log(err);
            });
            tx.executeSql('SELECT COUNT(*) AS NUM FROM GroupList',[],function(tx,mes){
              console.log(mes.rows[0].NUM);
              if(mes.rows[0].NUM==0){
                console.log("插入组别数据");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(1,1,'1号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(2,1,'2号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(3,1,'3号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(4,1,'4号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(5,1,'5号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(6,1,'6号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(7,1,'7号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(8,1,'拆迁剩余','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(9,2,'西薛家泾','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(10,2,'东薛家泾','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(11,2,'盛园小区','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(12,3,'1号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(13,3,'2号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(14,3,'3号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(15,3,'4号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(16,3,'5号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(17,3,'6号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(18,3,'7号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(19,3,'8号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(20,4,'电站花苑','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(21,4,'拆迁剩余','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(22,5,'明星小区','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(23,5,'东林佳苑','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(24,5,'拆迁剩余','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(25,6,'1号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(26,6,'2号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(27,6,'3号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(28,6,'4号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(29,6,'5号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(30,6,'6号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(31,6,'7号','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(32,6,'伟阳小区','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(33,6,'景园、逸园','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(34,6,'城北AB','c')");
                tx.executeSql("insert into GroupList(GroupID,CountryID,Name,IsChoose)values(35,6,'拆迁剩余','c')");
              }
            },function(tx,err){
              console.log(err);
            });
          });			

④下面做一个简单的页面展示

<template>
  <div id="test">
    	<!-- 此处展示城镇列表 -->
      <h2>城镇</h2>
			<div class="fl">
				<p v-for="i in citylist" :key="i.CityID" >{{i.Name}}</p>
			</div>
      <!-- 此处展示村落列表 -->
      <h2>村落</h2>
			<div class="fl">
				<p v-for="i in countrylist" :key="i.CountyID" >{{i.Name}}</p>
			</div>
      <!-- 此处展示组别列表 -->
      <h2>组别</h2>
			<div class="fl">
				<p v-for="i in grouplist" :key="i.GroupID">{{i.Name}}</p>
			</div>
  </div>
</template>
  methods: {
          selcity:function(){//查询城镇
            var that=this;//与this区别开
            that.citylist=[];
            this.$db.transaction(function(tx){
              tx.executeSql("select * from City",[],function(tx,res){
                  for(var i=0;i<res.rows.length;i++){
                    that.citylist.push(res.rows[i]);
                  }
                },function(tx,err){
                  console.log(err);
                }
              );
            });		
          },
          selcounty:function(){//查询乡村
            var that=this;//与this区别开
            that.countrylist=[];
            this.$db.transaction(function(tx){
              tx.executeSql("select * from County",[],function(tx,res){
                  for(var i=0;i<res.rows.length;i++){
                    that.countrylist.push(res.rows[i]);
                  }
                },function(tx,err){
                  console.log(err);
                }
              );
            });		
          },
          selgroup:function(){//查询组别
            var that=this;//与this区别开
            that.grouplist=[];
            this.$db.transaction(function(tx){
              tx.executeSql("select * from GroupList",[],function(tx,res){
                  for(var i=0;i<res.rows.length;i++){
                    that.grouplist.push(res.rows[i]);
                  }
                },function(tx,err){
                  console.log(err);
                }
              );
            });		
          }
        }

三、详细代码已上传GitHub,地址如下:

1、https://github.com/736755244/Test 


欢迎留言,一起交流学习!

Vue3项目实战:用localForage替代localStorage的5个理由(附完整配置代码) 本文详细解析了在Vue3项目中使用localForage替代localStorage的五大优势,包括突破存储容量限制、异步操作、多数据类型支持等。通过完整配置代码和实战案例,帮助开发者高效实现前端本地存储升级,提升应用性能和开发体验。 阅读详情

相关推荐

前端数据存储方案:WebSQL、localStorage与jQuery实战解析

前端数据存储是Web开发中的基础技术,涉及多种存储方案的选择与优化。键值对存储如localStorage适合简单数据,支持跨会话持久化,但需注意序列化与存储空间限制;关系型存储如WebSQL(基于SQLite)适合复杂数据结构,支持事务与索引优化,但需考虑兼容性问题。这些技术在电商购物车、离线应用等场景中发挥关键作用。通过合理组合存储方案,开发者可以构建更健壮的Web应用。本文结合localStorage序列化与WebSQL索引优化等实战案例,深入解析前端存储的最佳实践。

weixin_32430941的博客 289

如何在Vue项目中使用websql数据库

*在移动端项目开发中,可能需要因为项目的特殊性需要在本地存储大量的数据,因为我选择使用websql数据库来实现大量数据的存储。 **对于一些懂数据库的可以很好的理解websql,说到底其实他就是一个存在于浏览器端的小型数据库 首先我们先构建自己的Vue项目,构建完成后。新建一个JS放在那里都可以。 比如我在Src目录下新建了一个webSql文件用来写我的数据库链接。 然后我们进入自己的we...

我的代码没有Bug的博客 9896

Vue3项目实战:localForage异步存储优化与多实例管理

本文深入探讨了在Vue3项目中如何利用localForage替代传统的localStorage,实现异步、大容量的本地存储。文章详细介绍了localForage的集成、核心API使用、多实例管理策略以解决复杂业务的数据隔离问题,并提供了异步操作优化、缓存封装及Vue3 Composable实践等高级技巧,旨在帮助开发者构建更流畅、可维护的前端应用。

weixin_29014237的博客 885

在vue中使用HTML5 Web SQL 浏览器数据库

HTML5 Web SQL 数据库 Web SQL 是在浏览器上模拟数据库,可以使用 JS 来操作 SQL 完成对数据的读写。\ Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。 如果你是一个 Web 后端程序员,应该很容易理解 SQL 的操作。 Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。 核心方法 以下是规范中定义的三个核心方法: openDataba

qq_42753705的博客 1143

前端本地存储方案-localForage-vue3中使用

localForage 是一个快速而简单的 JavaScript 存储库。通过使用异步存储(IndexedDB 或 WebSQL)和简单的类 localStorage 的 API ,localForage 能改善 Web 应用的离线体验。 在不支持 IndexedDB 或 WebSQL 的浏览器中,localForage 使用 localStorage

qq_37656005的博客 5931

Vue项目里Websocket的使用

由于项目需求有要使用长链接,我们普通的http请求如果用轮询的方式与服务端通讯就很消耗资源。我们一起来学习一下在vue项目里如何使用websocket,本文纯属个人观点,如果有不正确的地方请大家批评指正,技术无高低,谦虚学习的心态我认为很重要,天外有天人外有人。

qq_37635012的博客 2万+

vue基于WebSql实现的仿redis前端缓存,前端实现请求接口数据缓存

我的使用场景 防止用户过渡刷新或切换界面,不断的请求后端接口,所以在前端对用户拿到的部分数据进行缓存。 目录结构 WebSql.js 创建数据库表,储存key,value,过期时间 import Vue from 'vue' import {executeSql} from '@/utils/localDb' const WebSql=function(){ if(window.openDatabase){ //openDatabase('数据库名称','版本','数据库描述',

小宝的博客 1063

基于Vue+Element-UI与WebSQL的前端本地存储实战项目

*** 创建一条记录* @param {string} table 表名* @param {object} data 数据对象* @returns {Promise<number>} 返回新记录 ID*//*** 根据 ID 查询记录*//*** 条件查询* @param {object} conditions 键值对条件*//*** 更新记录*//*** 删除记录*/该接口定义了基本的 CRUD 操作契约,所有具体实现都必须遵循。

weixin_42588877的博客 661

vue浏览器websql ,websql只支持部分浏览器

this.$db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS userInfo (userInfoID unique primary key , userInfoDeatil , Timestamp)'); tx.executeSql('SELECT COUNT(*) AS NUM FROM userInfo', [], funct

qq_31889029的博客 771

vue+element-ui+websql

使用vue+elemetnui框架,采用websql/localsotrage作为数据存储,实现增删改查

别再为H5扫码头疼了!用Vue3 + vue-qrcode-reader,5分钟搞定移动端摄像头调用(附完整代码)

本文详细介绍了如何使用Vue3和vue-qrcode-reader快速实现移动端扫码功能,解决H5开发中常见的摄像头调用和兼容性问题。通过完整的代码示例和优化技巧,帮助开发者高效集成二维码识别功能,提升用户体验和开发效率。

weixin_33737134的博客 498

关于webSQL的总结

关于webSQL的使用总结 webSQL是浏览器自带的本地储存库之一,使用方法和Android的手机端sqLite是一样的, 用方法创库,用方法建表 //建库 let myBase = window.openDatabase("fristBase.db","1.0",null,20000); myBase是该数据库对象:参数 数据库名称 版本号 描述文本(null) 数据库大小 创建回调(省略)...

jinqianwang的博客 6320

手把手拆解DGX GB200 NVL72:1个机柜如何塞进72块GPU?详解NVLink Switch铜缆背板设计

本文深度解析英伟达DGX GB200 NVL72系统如何通过NVLink Switch铜缆背板设计,在标准42U机柜中集成72块B200 GPU,实现1800GB/s的超高带宽。文章详细介绍了模块化架构、铜缆互连技术、液冷散热方案和高密度供电系统等核心创新,为AI算力需求提供突破性解决方案。

red88的博客 1537

前端数据库——WebSQL和IndexedDB

前端数据库——WebSQL和IndexedDB - TheFirstDream - 博客园

u012632105的博客 473

SoC 验证老兵手册

《SoC验证老兵手册》摘要: 针对大型SoC系统级验证,手册提出Cache+DMA场景的高效验证方案。核心方法采用C测试用例(模拟Linux/RTOS真实场景)触发隐蔽bug,配合SV Checker精准捕捉硬件问题(如DMA读取脏缓存行)。特别强调验证方法论:C用例负责复杂行为模拟,SV专注RTL正确性检查;利用Linux天然并发性暴露硬件缺陷。手册还包含模拟面试攻防技巧,指出验证架构师需具备定义Stimulus/Checker边界的能力。终极判断标准:未通过Linux下Cache+DMA+SMP+中断测

元直的博客 1356

SAP CEWB 高效批量调整工艺路线与BOM的实战指南

本文详细介绍了SAP CEWB工具在批量调整工艺路线与BOM中的高效应用。通过实战案例和操作指南,帮助制造业企业快速掌握批量修改技巧,显著提升工作效率,避免手工操作带来的错误和耗时。特别适合需要频繁更新工艺路线和BOM的企业用户。

weixin_42524708的博客 393

前端本地存储数据库IndexedDB

前端本地化存储算是一个老生常谈的话题了,我们对于存储量小:即使是web storage的存储量最大也只有 5M;存取不方便:存入的内容会经过序列化,当存入非字符串的时候,取值的时候需要通过反序列化。当我们的存储量比较大的时候,我们一定会想到我们的indexedDB,让我们在浏览器中也可以使用数据库这种形式来玩转本地化存储,然而indexedDB的使用是比较繁琐而复杂的,有一定的学习成本,但第三方库的出现,让我们轻松无负担的在浏览器中使用indexedDB。截止今天,在github的star已经。

DZQ1223的博客 540

Atlas 300I Pro推理卡性能深度测试:对比业界同类产品的能效比与算力表现

本文对昇腾Atlas 300I Pro推理卡进行了深度性能评测,重点对比了其与业界同类产品的能效比与算力表现。实测数据显示,该卡在运行BERT等模型时展现出高达39.6句子/秒/瓦的卓越能效比,电力成本可降低40%以上,同时其达芬奇架构和硬件加速特征检索能力,为高密度在线推理和向量检索场景提供了强大支撑。

weixin_29031161的博客 572

基于vue学生成绩管理系统

基于vue实现学生成绩管理系统

weixin_42280470的博客 1万+

虚幻商城 蓝图汇总

虚幻引擎是一个非常强大和灵活的游戏开发工具,拥有众多的蓝图可以帮助我们更高效地工作。

一碗清深的博客 1500

SimSwap复现指引及代码分析【2023有更新】

我的环境!!!😚😚😚 之后会遇到:还会遇到至此环境配置完毕!下面是所需要的checkpoint。至此环境准备结束。先试试环境是否有问题,图片是代码包中给的。我用的是512的checkpoint,无水印,a是源脸,b是目标脸。输出到./output/result_whole_swapsingle.jpg 如图是可以成功换脸的:(为了方便查看将图像裁剪到了128x128) 表示图像预处理,相应的改为也是一样。不加就是对已经面部对齐的图像进行简单的面部交换。 加上就是无水印。 交换一张图片中的所有面孔。

zik的博客 2042

localforage本地存储(融合Web Storage,Web SQL Database,ndexedDB三种前端存储)

localforage本地存储

bamboozjy的博客 736

SerDes学习笔记:DFE均衡架构示例(USB3.1、PCIe3.0\4.0)

本文探讨了DFE均衡器架构在不同数据接口中的应用特性。研究表明,抽头数量随数据速率提升而增加,1-16抽头架构较为常见。通过PCIeGen3/4实例分析,对比了单抽头、双抽头和15抽头DFE的性能差异,证明多抽头结构能通过精细调节有效提升噪声容限和降低误码率。文章详细阐述了DFE工作原理,包括其通过反馈信号对输入信号的补偿机制,以及不同抽头对消除码间干扰的作用。实验采用8Gbps速率(125ps/UI)进行波形仿真,直观展示了均衡处理前后的信号变化,为理解信道均衡技术提供了重要参考。

一只豌豆象的博客 504

SpringBoot+Vue前后端分离及交互

什么是前后端分离? 将一个应用的前后端代码分开写 为什么要前后端分离? 在传统的Javaweb开发中,往往是前端人员写好html后,再由后端人员将java整合其中,变成JSP。 如此一来就造成了沟通不便、降低效率、前后端耦合度高等问题。 前后端分离是如何解决此问题的呢? 前端写客户端代码,后端写服务端代码并提供接口 前端通过ajax请求访问接口,将model展示到view中 如此前后端只需要约定接口文档(URL、参数、数据类型),之后便分别独立开发。前端可以通过json造假数据进行测试,后端用postman

D_ps19990501的博客 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

前端数据存储

记录一些前端数据存储的方法!

前后端分离,人不分离! 801

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【前端技术】LocalForage数据存储

LocalForage是一个方便易用的浏览器端数据存储库,它提供了一致的API和跨浏览器支持,使开发者能够轻松地在Web应用程序中进行本地数据存储。通过使用LocalForage,您可以实现可靠的浏览器端数据存储,并构建出更强大、更可靠的Web应用程序。

俊刚的博客 1891

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

下一篇: VUE中导出Excel功能的实现
前端的小小对象
博客等级 码龄11年 171粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值