代码规范

原文链接:https://blog.csdn.net/caijunfen/article/details/86548895###

Vue 开发规范目录及说明

本文档为前端 vue 开发规范

  • 规范目的
  • 命名规范
  • 结构化规范
  • 注释规范
  • 编码规范
  • CSS 规范

规范目的

为提高团队协作效率

便于后台人员添加功能及前端后期优化维护

输出高质量的文档

命名规范

为了让大家书写可维护的代码,而不是一次性的代码

让团队当中其他人看你的代码能一目了然

甚至一段时间时候后你再看你某个时候写的代码也能看

普通变量命名规范

  • 命名方法 :驼峰命名法

  • 命名规范 :

    <ol><li>
    	<p>命名必须是跟需求的内容相关的词,比如说我想申明一个变量,用来表示我的学校,那么我们可以这样定义<code>const mySchool = "我的学校"</code>;</p>
    	</li>
    	<li>
    	<p>命名是复数的时候需要加<strong>s</strong>,比如说我想申明一个数组,表示很多人的名字,那么我们可以这样定义<code>const names = new Array()</code>;</p>
    	</li>
    </ol></li>
    

常量

  • 命名方法 : 全部大写
  • 命名规范 : 使用大写字母和下划线来组合命名,下划线用以分割单词。

 
 
  1. const MAX_COUNT = 10
  2. const URL = 'https://www.baidu.com/'
  3. 复制代码

组件命名规范

官方文档推荐及使用遵循规则:

PascalCase (单词首字母大写命名)是最通用的声明约定

kebab-case (短横线分隔命名) 是最通用的使用约定

  • 组件名应该始终是多个单词的,根组件 App 除外

  • 有意义的名词、简短、具有可读性

  • 命名遵循 PascalCase 约定

    <ul><li>
    	<p>公用组件以 Abcd (公司名缩写简称) 开头,如(<code>AbcdDatePicker,AbcdTable</code>)</p>
    	</li>
    	<li>
    	<p>页面内部组件以组件模块名简写为开头,Item 为结尾,如(<code>StaffBenchToChargeItem,StaffBenchAppNotArrItem</code>)</p>
    	</li>
    </ul></li>
    <li>
    <p>使用遵循 kebab-case 约定</p>
    
    <ul><li>在页面中使用组件需要前后闭合,并以短线分隔,如(<code>&lt;abcd-date-picker&gt;&lt;/abcd-date-picker&gt;,&lt;abcd-table&gt;&lt;/abcd-table&gt;</code>)</li>
    </ul></li>
    <li>
    <p>导入及注册组件时,遵循 PascalCase 约定</p>
    </li>
    <li>
    <p>同时还需要注意:必须符合自定义元素规范: 切勿使用保留字。</p>
    </li>
    

method 方法命名命名规范

  • 驼峰式命名,统一使用动词或者动词+名词形式

 
 
  1. //bad
  2. go、nextPage、show、open、login
  3. // good
  4. jumpPage、openCarInfoDialog
  5. 复制代码
  • 请求数据方法,以 data 结尾

 
 
  1. //bad
  2. takeData、confirmData、getList、postForm
  3. // good
  4. getListData、postFormData
  5. 复制代码
  • init、refresh 单词除外

  • 尽量使用常用单词开头(set、get、go、can、has、is)

附: 函数方法常用的动词:


 
 
  1. get 获取/ set 设置,
  2. add 增加/remove 删除
  3. create 创建/destory 移除
  4. start 启动/ stop 停止
  5. open 打开/ close 关闭,
  6. read 读取/write 写入
  7. load 载入/ save 保存,
  8. create 创建/destroy 销毁
  9. begin 开始/ end 结束,
  10. backup 备份/ restore 恢复
  11. import 导入/ export 导出,
  12. split 分割/ merge 合并
  13. inject 注入/ extract 提取,
  14. attach 附着/detach 脱离
  15. bind 绑定/separate 分离,
  16. view 查看/browse 浏览
  17. edit 编辑/ modify 修改,
  18. select 选取/mark 标记
  19. copy 复制/paste 粘贴,
  20. undo 撤销/ redo 重做
  21. insert 插入/ delete 移除,
  22. add 加入/append 添加
  23. clean 清理/ clear 清除,
  24. index 索引/ sort 排序
  25. find 查找/ search 搜索,
  26. increase 增加/decrease 减少
  27. play 播放/pause 暂停,
  28. launch 启动/run 运行
  29. compile 编译/ execute 执行,
  30. debug 调试/ trace 跟踪
  31. observe 观察/listen 监听,
  32. build 构建/publish 发布
  33. input 输入/ output 输出,
  34. encode 编码/ decode 解码
  35. encrypt 加密/ decrypt 解密,
  36. compress 压缩/decompress 解压缩
  37. pack 打包/unpack 解包,
  38. parse 解析/emit 生成
  39. connect 连接/ disconnect 断开,
  40. send 发送/receive 接收
  41. download 下载/upload 上传,
  42. refresh 刷新/synchronize 同步
  43. update 更新/revert 复原,
  44. lock 锁定/ unlock 解锁
  45. check out 签出/ check in 签入,
  46. submit 提交/ commit 交付
  47. push 推/pull 拉,
  48. expand 展开/collapse 折叠
  49. begin 起始/ end 结束,
  50. start 开始/ finish 完成
  51. enter 进入/ exit 退出,
  52. abort 放弃/quit 离开
  53. obsolete 废弃/depreciate 废旧,
  54. collect 收集/ aggregate 聚集
  55. 复制代码

views 下的文件命名

  • 只有一个文件的情况下不会出现文件夹,而是直接放在 views 目录下面,如 index.vue

  • 尽量是名词,且使用驼峰命名法

  • 开头的单词就是所属模块名字(workbenchIndex、workbenchList、workbenchEdit)

  • 名字至少两个单词(good: workbenchIndex)(bad:workbench)

props 命名

在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板中应该始终使用 kebab-case


 
 
  1. <!-- bad -->
  2. <script>
  3. props: {
  4. 'greeting-text': String
  5. }
  6. </script>
  7. <welcome-message greetingText="hi"> </welcome-message>
  8. <!-- good -->
  9. <script>
  10. props: {
  11. greetingText: String
  12. }
  13. </script>
  14. <welcome-message greeting-text="hi"> </welcome-message>
  15. 复制代码

例外情况

  1. 作用域不大临时变量可以简写,比如:str,num,bol,obj,fun,arr。

  2. 循环变量可以简写,比如:i,j,k 等。

结构化规范

目录文件夹及子文件规范

  • 以下统一管理处均对应相应模块
  • 以下全局文件文件均以 index.js 导出,并在 main.js 中导入
  • 以下临时文件,在使用后,接口已经有了,发版后清除

 
 
  1. src 源码目录
  2. | -- api 接口,统一管理
  3. | -- assets 静态资源,统一管理
  4. | -- components 公用组件,全局文件
  5. | -- filters 过滤器,全局工具
  6. | -- icons 图标,全局资源
  7. | -- datas 模拟数据,临时存放
  8. | -- lib 外部引用的插件存放及修改文件
  9. | -- mock 模拟接口,临时存放
  10. | -- router 路由,统一管理
  11. | -- store vuex, 统一管理
  12. | -- views 视图目录
  13. | | -- staffWorkbench 视图模块名
  14. | | -- |-- staffWorkbench.vue 模块入口页面
  15. | | -- |-- indexComponents 模块页面级组件文件夹
  16. | | -- |-- components 模块通用组件文件夹
  17. 复制代码

vue 文件基本结构


 
 
  1. <template>
  2. <div>
  3. <!--必须在div中编写页面-->
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. components : {
  9. },
  10. data () {
  11. return {
  12. }
  13. },
  14. mounted() {
  15. },
  16. methods: {
  17. }
  18. }
  19. </script>
  20. <!--声明语言,并且添加scoped-->
  21. <style lang="scss" scoped>
  22. </style>
  23. 复制代码

多个特性的元素规范

多个特性的元素应该分多行撰写,每个特性一行。(增强更易读)


 
 
  1. <!-- bad -->
  2. <img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
  3. <my-component foo="a" bar="b" baz="c"> </my-component>
  4. <!-- good -->
  5. <img
  6. src= "https://vuejs.org/images/logo.png"
  7. alt= "Vue Logo"
  8. >
  9. <my-component
  10. foo= "a"
  11. bar= "b"
  12. baz= "c"
  13. >
  14. </my-component>
  15. 复制代码

元素特性的顺序

原生属性放前面,指令放后面

如下所示:


 
 
  1. - class
  2. - id,ref
  3. - name
  4. - data-*
  5. - src, for, type, href,value,max-length,max,min,pattern
  6. - title, alt,placeholder
  7. - aria-*, role
  8. - required, readonly,disabled
  9. - is
  10. - v- for
  11. - key
  12. - v- if
  13. - v- else- if
  14. - v- else
  15. - v-show
  16. - v-cloak
  17. - v-pre
  18. - v-once
  19. - v-model
  20. - v-bind,:
  21. - v- on,@
  22. - v-html
  23. - v- text
  24. 复制代码

组件选项顺序

如下所示:


 
 
  1. - components
  2. - props
  3. - data
  4. - computed
  5. - created
  6. - mounted
  7. - metods
  8. - filter
  9. - watch
  10. 复制代码

注释规范

代码注释在一个项目的后期维护中显的尤为重要,所以我们要为每一个被复用的组件编写组件使用说明,为组件中每一个方法编写方法说明

务必添加注释列表

  1. 公共组件使用说明

  2. 各组件中重要函数或者类说明

  3. 复杂的业务逻辑处理说明

  4. 特殊情况的代码处理说明,对于代码中特殊用途的变量、存在临界值、函数中使用的 hack、使用了某种算法或思路等需要进行注释描述

  5. 多重 if 判断语句

  6. 注释块必须以/**(至少两个星号)开头**/

  7. 单行注释使用//

单行注释

注释单独一行,不要在代码后的同一行内加注释。例如:


 
 
  1. bad
  2. var name =”abc”; // 姓名
  3. good
  4. // 姓名
  5. var name = “abc”;
  6. 复制代码

多行注释


 
 
  1. 组件使用说明,和调用说明
  2. /**
  3. * 组件名称
  4. * @module 组件存放位置
  5. * @desc 组件描述
  6. * @author 组件作者
  7. * @date 2017120517: 22: 43
  8. * @param {Object} [title] - 参数说明
  9. * @param {String} [columns] - 参数说明
  10. * @example 调用示例
  11. * <hbTable :title= "title" :columns= "columns" :tableData= "tableData">< /hbTable>
  12. **/
  13. 复制代码

编码规范

优秀的项目源码,即使是多人开发,看代码也如出一人之手。统一的编码规范,可使代码更易于阅读,易于理解,易于维护。尽量按照 ESLint 格式要求编写代码

源码风格

使用 ES6 风格编码

  1. 定义变量使用 let ,定义常量使用 const

  2. 静态字符串一律使用单引号或反引号,动态字符串使用反引号


 
 
  1. // bad
  2. const a = 'foobar'
  3. const b = 'foo' + a + 'bar'
  4. // acceptable
  5. const c = `foobar`
  6. // good
  7. const a = 'foobar'
  8. const b = `foo${a}bar`
  9. const c = 'foobar'
  10. 复制代码
  1. 解构赋值
  • 数组成员对变量赋值时,优先使用解构赋值

 
 
  1. // 数组解构赋值
  2. const arr = [ 1, 2, 3, 4]
  3. // bad
  4. const first = arr[ 0]
  5. const second = arr[ 1]
  6. // good
  7. const [first, second] = arr
  8. 复制代码
  • 函数的参数如果是对象的成员,优先使用解构赋值

 
 
  1. // 对象解构赋值
  2. // bad
  3. function getFullName(user) {
  4. const firstName = user.firstName
  5. const lastName = user.lastName
  6. }
  7. // good
  8. function getFullName(obj) {
  9. const { firstName, lastName } = obj
  10. }
  11. // best
  12. function getFullName({ firstName, lastName }) {}
  13. 复制代码
  1. 拷贝数组

    <p>使用扩展运算符(...)拷贝数组。</p>
    </li>
    

 
 
  1. const items = [ 1, 2, 3, 4, 5]
  2. // bad
  3. const itemsCopy = items
  4. // good
  5. const itemsCopy = [...items]
  6. 复制代码
  1. 箭头函数

    <p>需要使用函数表达式的场合,尽量用箭头函数代替。因为这样更简洁,而且绑定了 this</p>
    </li>
    

 
 
  1. // bad
  2. const self = this;
  3. const boundMethod = function(...params) {
  4. return method.apply(self, params);
  5. }
  6. // acceptable
  7. const boundMethod = method.bind( this);
  8. // best
  9. const boundMethod = (...params) => method.apply( this, params);
  10. 复制代码
  1. 模块
  • 如果模块只有一个输出值,就使用 export default,如果模块有多个输出值,就不使用 export default,export default 与普通的 export 不要同时使用

 
 
  1. // bad
  2. import * as myObject from './importModule'
  3. // good
  4. import myObject from './importModule'
  5. 复制代码
  • 如果模块默认输出一个函数,函数名的首字母应该小写。

 
 
  1. function makeStyleGuide() {
  2. }
  3. export default makeStyleGuide;
  4. 复制代码
  • 如果模块默认输出一个对象,对象名的首字母应该大写。

 
 
  1. const StyleGuide = {
  2. es6: {
  3. }
  4. };
  5. export default StyleGuide;
  6. 复制代码

指令规范

  1. 指令有缩写一律采用缩写形式

 
 
  1. // bad
  2. v-bind: class= "{'show-left':true}"
  3. v-on:click= "getListData"
  4. // good
  5. : class= "{'show-left':true}"
  6. @click= "getListData"
  7. 复制代码
  1. v-for 循环必须加上 key 属性,在整个 for 循环中 key 需要唯一

 
 
  1. <!-- good -->
  2. <ul>
  3. <li v-for="todo in todos" :key="todo.id">
  4. {{ todo.text }}
  5. </li>
  6. </ul>
  7. <!-- bad -->
  8. <ul>
  9. <li v-for="todo in todos">
  10. {{ todo.text }}
  11. </li>
  12. </ul>
  13. 复制代码
  1. 避免 v-if 和 v-for 同时用在一个元素上(性能问题)

    <p>以下为两种解决方案:</p>
    </li>
    
  • 将数据替换为一个计算属性,让其返回过滤后的列表

 
 
  1. <!-- bad -->
  2. <ul>
  3. <li v-for="user in users" v-if="user.isActive" :key="user.id">
  4. {{ user.name }}
  5. </li>
  6. </ul>
  7. <!-- good -->
  8. <ul>
  9. <li v-for="user in activeUsers" :key="user.id">
  10. {{ user.name }}
  11. </li>
  12. </ul>
  13. <script>
  14. computed: {
  15. activeUsers: function () {
  16. return this.users.filter( function (user) {
  17. return user.isActive
  18. })
  19. }
  20. }
  21. </script>
  22. 复制代码
  • 将 v-if 移动至容器元素上 (比如 ul, ol)

 
 
  1. <!-- bad -->
  2. <ul>
  3. <li v-for="user in users" v-if="shouldShowUsers" :key="user.id">
  4. {{ user.name }}
  5. </li>
  6. </ul>
  7. <!-- good -->
  8. <ul v-if="shouldShowUsers">
  9. <li v-for="user in users" :key="user.id">
  10. {{ user.name }}
  11. </li>
  12. </ul>
  13. 复制代码

Props 规范

Props 定义应该尽量详细


 
 
  1. // bad 这样做只有开发原型系统时可以接受
  2. props: [ 'status']
  3. // good
  4. props: {
  5. status: {
  6. type: String,
  7. required: true,
  8. validator: function (value) {
  9. return [
  10. 'syncing',
  11. 'synced',
  12. 'version-conflict',
  13. 'error'
  14. ].indexOf(value) !== -1
  15. }
  16. }
  17. }
  18. 复制代码

其他

  1. 避免 this.$parent

  2. 调试信息 console.log() debugger 使用完及时删除

  3. 除了三目运算,if,else 等禁止简写


 
 
  1. // bad
  2. if ( true)
  3. alert(name);
  4. console.log(name);
  5. // bad
  6. if ( true)
  7. alert(name);
  8. console.log(name)
  9. // good
  10. if ( true) {
  11. alert(name);
  12. }
  13. console.log(name);
  14. 复制代码

CSS 规范

通用规范

  1. 统一使用"-"连字符

  2. 省略值为 0 时的单位


 
 
  1. // bad
  2. padding-bottom: 0px;
  3. margin: 0em;
  4. // good
  5. padding-bottom: 0;
  6. margin: 0;
  7. 复制代码
  1. 如果 CSS 可以做到,就不要使用 JS

  2. 建议并适当缩写值,提高可读性,特殊情况除外

    <p>“建议并适当”是因为缩写总是会包含一系列的值,而有时候我们并不希望设置某一值,反而造成了麻烦,那么这时候你可以不缩写,而是分开写。</p>
    
    <p>当然,在一切可以缩写的情况下,请务必缩写,它最大的好处就是节省了字节,便于维护,并使阅读更加一目了然。</p>
    </li>
    

 
 
  1. // bad
  2. .box{
  3. border-top-style: none;
  4. font-family: palatino, georgia, serif;
  5. font-size: 100%;
  6. line-height: 1.6;
  7. padding-bottom: 2em;
  8. padding- left: 1em;
  9. padding- right: 1em;
  10. padding-top: 0;
  11. }
  12. // good
  13. .box{
  14. border-top: 0;
  15. font: 100%/ 1.6 palatino, georgia, serif;
  16. padding: 0 1em 2em;
  17. }
  18. 复制代码
  1. 声明应该按照下表的顺序

左到右,从上到下

显示属性自身属性文本属性和其他修饰
displaywidthfont
visibilityheighttext-align
positionmargintext-decoration
floatpaddingvertical-align
clearborderwhite-space
list-styleoverflowcolor
topmin-widthbackground

 
 
  1. // bad
  2. .box {
  3. font-family: 'Arial', sans-serif;
  4. border: 3px solid #ddd;
  5. left: 30%;
  6. position: absolute;
  7. text-transform: uppercase;
  8. background-color: #eee;
  9. right: 30%;
  10. isplay: block;
  11. font-size: 1.5rem;
  12. overflow: hidden;
  13. padding: 1em;
  14. margin: 1em;
  15. }
  16. // good
  17. .box {
  18. display: block;
  19. position: absolute;
  20. left: 30%;
  21. right: 30%;
  22. overflow: hidden;
  23. margin: 1em;
  24. padding: 1em;
  25. background-color: #eee;
  26. border: 3px solid #ddd;
  27. font-family: 'Arial', sans-serif;
  28. font-size: 1.5rem;
  29. text-transform: uppercase;
  30. }
  31. 复制代码
  1. 元素选择器应该避免在 scoped 中出现

    <p><a href="https://link.juejin.im?target=https%3A%2F%2Fcn.vuejs.org%2Fv2%2Fstyle-guide%2F%23scoped-%25E4%25B8%25AD%25E7%259A%2584%25E5%2585%2583%25E7%25B4%25A0%25E9%2580%2589%25E6%258B%25A9%25E5%2599%25A8-%25E8%25B0%25A8%25E6%2585%258E%25E4%25BD%25BF%25E7%2594%25A8" rel="nofollow">官方文档说明</a>:在 scoped 样式中,类选择器比元素选择器更好,因为大量使用元素选择器是很慢的。</p>
    </li>
    <li>
    <p>分类的命名方法</p>
    
    <p>使用单个字母加上"-"为前缀</p>
    
    <p>布局(grid)(.g-);</p>
    
    <p>模块(module)(.m-);</p>
    
    <p>元件(unit)(.u-);</p>
    
    <p>功能(function)(.f-);</p>
    
    <p>皮肤(skin)(.s-);</p>
    
    <p>状态(.z-)。</p>
    </li>
    <li>
    <p>统一语义理解和命名</p>
    </li>
    

布局(.g-)

语义命名简写
文档docdoc
头部headhd
主体bodybd
尾部footft
主栏mainmn
主栏子容器maincmnc
侧栏sidesd
侧栏子容器sidecsdc
盒容器wrap/boxwrap/box

模块(.m-)、元件(.u-)

语义命名简写
导航navnav
子导航subnavsnav
面包屑crumbcrm
菜单menumenu
选项卡tabtab
标题区head/titlehd/tt
内容区body/contentbd/ct
列表listlst
表格tabletb
表单formfm
热点hothot
排行toptop
登录loginlog
标志logologo
广告advertisead
搜索searchsch
幻灯slidesld
提示tipstips
帮助helphelp
新闻newsnews
下载downloaddld
注册registreg
投票votevote
版权copyrightcprt
结果resultrst
标题titlett
按钮buttonbtn
输入inputipt

功能(.f-)

语义命名简写
浮动清除clearbothcb
向左浮动floatleftfl
向右浮动floatrightfr
内联块级inlineblockib
文本居中textaligncentertac
文本居右textalignrighttar
文本居左textalignlefttal
垂直居中verticalalignmiddlevam
溢出隐藏overflowhiddenoh
完全消失displaynonedn
字体大小fontsizefs
字体粗细fontweightfw

皮肤(.s-)

语义命名简写
字体颜色fontcolorfc
背景backgroundbg
背景颜色backgroundcolorbgc
背景图片backgroundimagebgi
背景定位backgroundpositionbgp
边框颜色bordercolorbdc

状态(.z-)

语义命名简写
选中selectedsel
当前currentcrt
显示showshow
隐藏hidehide
打开openopen
关闭closeclose
出错errorerr
不可用disableddis

sass 规范

  1. 当使用 Sass 的嵌套功能的时候,重要的是有一个明确的嵌套顺序,以下内容是一个 SCSS 块应具有的顺序。

    <ol><li>当前选择器的样式属性</li>
    	<li>父级选择器的伪类选择器 (:first-letter, :hover, :active etc)</li>
    	<li>伪类元素 (:before and :after)</li>
    	<li>父级选择器的声明样式 (.selected, .active, .enlarged etc.)</li>
    	<li>用 Sass 的上下文媒体查询</li>
    	<li>子选择器作为最后的部分</li>
    </ol></li>
    

 
 
  1. .product-teaser {
  2. // 1. Style attributes
  3. display: inline-block;
  4. padding: 1rem;
  5. background-color: whitesmoke;
  6. color: grey;
  7. // 2. Pseudo selectors with parent selector
  8. &:hover {
  9. color: black;
  10. }
  11. // 3. Pseudo elements with parent selector
  12. &:before {
  13. content: "";
  14. display: block;
  15. border-top: 1px solid grey;
  16. }
  17. &:after {
  18. content: "";
  19. display: block;
  20. border-top: 1px solid grey;
  21. }
  22. // 4. State classes with parent selector
  23. &.active {
  24. background-color: pink;
  25. color: red;
  26. // 4.2. Pseuso selector in state class selector
  27. &:hover {
  28. color: darkred;
  29. }
  30. }
  31. // 5. Contextual media queries
  32. @media screen and (max-width: 640px) {
  33. display: block;
  34. font-size: 2em;
  35. }
  36. // 6. Sub selectors
  37. > .content > .title {
  38. font-size: 1.2em;
  39. // 6.5. Contextual media queries in sub selector
  40. @media screen and (max-width: 640px) {
  41. letter-spacing: 0.2em;
  42. text-transform: uppercase;
  43. }
  44. }
  45. }
  46. 复制代码

特殊规范

  • 对用页面级组件样式,应该是有作用域的
  • 对于公用组件或者全局组件库,我们应该更倾向于选用基于 class 的 BEM 策略

 
 
  1. <style lang='scss'> </style> // bad
  2. <!-- 使用 scoped 作用域 -->
  3. <style lang='scss' scoped> </style> // good
  4. <!-- 使用 BEM 约定 -->
  5. <style> // good
  6. .c-Button {
  7. border: none;
  8. border-radius: 2px;
  9. }
  10. .c-Button--close {
  11. background-color: red;
  12. }
  13. </style>


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值