8-Vue2

目录


8-1 webpack相关

//安装webpack
npm i webpack webpack-cli -D
//在根目录创建webpack.config.js的webpack配置
module.exports={
    mode:'development'//构建模式,development/production
}
//在 package.json 的 scripts 节点下,新增 dev 脚本如下:
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack"
  }
//在终端中运行 npm run dev 命令,启动 webpack 进行项目的打包构建

1.mode节点的可选值

mode 节点的可选值有两个,分别是:

① development

⚫ 开发环境

⚫ 不会对打包生成的文件进行代码压缩和性能优化

⚫ 打包速度快,适合在开发阶段使用

② production

⚫ 生产环境

⚫ 会对打包生成的文件进行代码压缩和性能优化

⚫ 打包速度很慢,仅适合在项目发布阶段使用

2.默认约定(可以在webpack.config.js中修改)

在 webpack 4.x 和 5.x 的版本中,有如下的默认约定:

① 默认的打包入口文件为 src -> index.js

② 默认的输出文件路径为 dist -> main.js

image-20230311190546527

3.webpack中的插件

① webpack-dev-server

⚫ 类似于 node.js 阶段用到的 nodemon 工具

⚫ 每当修改了源代码,webpack 会自动进行项目的打包和构建

npm install webpack-dev-server@3.11.2 -D
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve"
  }

② html-webpack-plugin

⚫ webpack 中的 HTML 插件(类似于一个模板引擎插件)

⚫ 可以通过此插件自定制 index.html 页面的内容

npm install html-webpack-plugin@5.3.2 -D

image-20230311193825430

4.webpack中的loader

在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块, webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错。

loader 加载器的作用:协助 webpack 打包处理特定的文件模块。

比如:

⚫ css-loader 可以打包处理 .css 相关的文件

⚫ less-loader 可以打包处理 .less 相关的文件

⚫ babel-loader 可以打包处理 webpack 无法处理的高级 JS 语法

8-2 基础入门

1.特性

1.1 数据驱动视图

在使用了 vue 的页面中,vue 会监听数据的变化,从而自动重新渲染页面的结构。

好处:当页面数据发生变化时,页面会自动重新渲染。

注意:数据驱动视图是单向的数据绑定。

1.2双向数据绑定

在填写表单时,双向数据绑定可以辅助开发者在不操作 DOM 的前提下,自动把用户填写的内容同步到数据源中。

好处:开发者不再需要手动操作 DOM 元素,来获取表单元素最新的值

1.3MVVM

MVVM 是 vue 实现数据驱动视图和双向数据绑定的核心原理。MVVM 指的是 Model、View 和 ViewModel

在 MVVM 概念中:

  • Model 表示当前页面渲染时所依赖的数据源。
  • View 表示当前页面所渲染的 DOM 结构。
  • ViewModel 表示 vue 的实例,它是 MVVM 的核心。

1.4vue的基本使用

image-20230311215401224

指定时不要用标签指定,只会处理第一个。最好要用id指定。

2.vue的指令与过滤器

2.1内容渲染指令

内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个:

v-text 【会覆盖元素的默认值】

<p v-text="gender">性别</p>

{{ }} 【插值】

<p>性别:{{gender}}</p>

v-html【可渲染标签】

info:'<p>元素</p>'
<p v-html="info"></p>

2.2属性绑定指令

v-bind/:

tips:'please input...'
<input type="text" v-bind:placeholder:"tips"/>
<input type="text" :placeholder:"tips"/>

tips:

在 vue 提供的模板渲染语法中,除了支持绑定简单的数据值之外,还支持 Javascript 表达式的运算。

{{2>3?'yes':'no'}}
<div :id="'list'+id"></div>

2.3事件绑定指令

v-on/@

    method:{
        add:function(n){
            console.log(vm.count+n)
        add(n){//推荐写法
         console.log(this.coutn+n)
         f(e){//event,简写为e
             e.target.style.backgroundColor='red'
         }
        }
        }
 <button v-on:click="add(2)">按钮</button>
<button @click="add(2)">按钮</button>

注意:原生 DOM 对象有 onclick、oninput、onkeyup 等原生事件,替换为 vue 的事件绑定形式后, 分别为:v-on:click、v-on:input、v-on:keyup

2.4$event

e v e n t 是 v u e 提供的特殊变量,用来表示原生的事件参数对象 e v e n t 。 event 是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。 eventvue提供的特殊变量,用来表示原生的事件参数对象eventevent 可以解决事件参数对象 event 被覆盖的问题

<button @click="add(2,$event)">按钮</button>
 f(n,e){//event,简写为e
             e.target.style.backgroundColor='red'
}

2.5修饰符

  • 事件修饰符

    在事件处理函数中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。因此, vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。常用的 5 个事件修饰符如下:

    image-20230312094724111

    <a href="#" @click.prevent="add">连接</a>
    
  • 按键修饰符

 <a href="#" @keyup.enter="submit">连接</a>

2.6双向绑定指令

v-model:在不操作 DOM 的前提下,快速获取表单的数据.

        <p>1:{{ password }}</p>
        <input type="text" v-model="password">

image-20230312101316924

相似的,value是单向数据绑定,数据源的改变才能引起页面的改变。

为了方便对用户输入的内容进行处理,vue 为 v-model 指令提供了 3 个修饰符,分别是:

image-20230312100300438

2.7条件渲染指令

条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏。

  • v-show
  • v-if (最常用)
  • v-else-if
  • v-else(必须和v-if一起用)
flag:true        
<p v-show="flag==true">true</p>
<p v-if="score==A">A</p>
<p v-else-if="score==B">B</p>
<p v-else>C</p>

两者区别:

实现原理不同:

  • v-if 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示与隐藏;
  • v-show 指令会动态为元素添加或移除 style=“display: none;” 样式,从而控制元素的显示与隐藏;

性能消耗不同:

v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此:

  • 如果需要非常频繁地切换,则使用 v-show 较好
  • 如果在运行时条件很少改变,则使用 v-if 较好

2.8列表渲染指令

v-for:基于一个数组来循环渲染一个列表结构。

v-for 指令需要使 用 item in items 形式的特殊语法,其中:

  • items 是待循环的数组
  • item 是被循环的每一项
data:{
	list:[
        {id:1,name:'zs'},
        {id:2,name:'ls'}
	]
}
<ul>
<li v-for="item in list">id:{{ item.id }}   姓名:{{ item.name }}</li>
</ul>
<li v-for="(item,index) in list">索引:{{ index }}   姓名:{{ item.name }}</li>
</ul>

item,index是形参,可以改为其他,如user,i

使用 key 维护列表的状态(建议用到v-for就用key)

当列表的数据变化时,默认情况下,vue 会尽可能的复用已存在的 DOM 元素,从而提升渲染的性能。但这种 默认的性能优化策略,会导致有状态的列表无法被正确更新。

为了给 vue 一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新的前提下,提升渲 染的性能。此时,需要为每项提供一个唯一的 key 属性:

<ul>
<li v-for="item in list" :key="item.id">姓名:{{ item.name }}</li>
</ul>

注意事项:

① key 的值只能是字符串或数字类型

② key 的值必须具有唯一性(即:key 的值不能重复)

③ 建议把数据项 id 属性的值作为 key 的值(因为 id 属性的值具有唯一性) 主键

④ 使用 index 的值当作 key 的值没有任何意义(因为 index 的值不具有唯一性)

⑤ 建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)

2.9过滤器

过滤器(Filters)是 vue 为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式{{}}v-bind 属性绑定

2.9.1定义过滤器
<!--插值表达式{{}}-->
<p>{{ username | capitalize}}</p>
<!--v-bind 属性绑定-->
<div v-bind:id="rawID | formatId"></div>
filters:{//过滤器一定要有返回值
	capitalize(val){//形参中的val是前面的值,即username
		//过滤器作用:首字母大写
		const first=val.charAt(0).toUpperCase()
		const other=val.slice(1)
		return first+other
}
}

注意:本质是个函数,要写在filters下,要有返回值

2.9.2私有/全局过滤器
  • 私有过滤器

    在 filters 节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前 vm 实例所控制的 el 区域内使用。

  • 全局过滤器

    Vue.filter("capitalize",function(val){
        const first=val.charAt(0).toUpperCase()
        const other=val.slice(1)
        return first+other
    })
    
2.9.4连续调用多个过滤器(串联调用)

image-20230312144332533

2.9.5过滤器传参

过滤器的本质是 JavaScript 函数,因此可以接收参数。

第一个参数是管道符前面的待处理值。

tips:vue3已经不支持过滤器了

3.侦听器

watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。

方法格式的侦听器:要监听的数据名作为方法名即可。

data:{
    username:'admin'
},
watch:{
	username(new,old){//新,旧
		console.log(new,old)
	}
}

无法在刚进入页面的时候自动触发;

如果侦听的是对象,对象中的属性变化侦听不到

对象格式的侦听器

data:{
    info:{username:'admin',password:'123'}
},
watch:{
	username:{
        handler(new){
            console.log(new.username)
        }
	}
}

可以通过immediate和deep解决以上缺点。

3.1immediate属性

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使 用 immediate 选项。示例代码如下:

watch: {
    username: {
    // handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
    handler: async function (newVal) {
    if (newVal === '') return
    const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
    console.log(res)
    },
    // 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
    immediate: true
    }
}

3.2deep属性

如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选项。

const vm=new Vue({
	el:'#app',
	data:{
		info:{username:'admin',password:'123'}
	},
	watch:{
		info:{
			handler(new){
				console.log(new.username)
			},
            deep:true
		}
	}
})

3.3侦听对象单个属性

watch:{
	'info.username':{
		handler(new){
			console.log(new)
		}
	}
}

4.计算属性

计算属性指的是通过一系列运算之后,最终得到一个属性值。

这个动态计算出来的属性值可以被模板结构或 methods 方法使用。

image-20230312164200033

① 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性

② 计算属性会缓存计算的结果,只有计算属性依赖的数据变化时,才会重新进行运算

5.vue-cli

安装:

npm install -g @vue/cli

5.1vue-cli的使用

在终端中:

vue create 项目名称

image-20230315201709980

image-20230315202556521

cd 项目名称
npm run serve

vue 要做的事情:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。

① App.vue 用来编写待渲染的模板结构

② index.html 中需要预留一个 el 区域

③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中

6.vue组件

.vue为后缀

每个 .vue 组件都由 3 部分构成,分别是:

  • template -> 组件的模板结构
  • script -> 组件的 JavaScript 行为
  • style -> 组件的样式

其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分

6.1template

  • template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
  • template 中只能包含唯一的根节点

6.2script

<script>//data、methods等
export default {//固定写法
	data:{//data 必须是一个函数,不能直接指向一个数据对象
		info:{username:'zhangsan'},
        //count:0		错误写法
	}
}
</script>

6.3style

<style lang="less">//lang="less"属性可以使用less语法
h1 {//普通语法
    font-weight:normal;
}
h1{//less语法
    font-weight:normal;
    span{
        color:red;
    }
}
</style>

6.4使用组件的步骤

image-20230312203743117

6.5全局/私有组件

通过components注册的组件是私有的。

例如: 在组件 A 的 components 节点下,注册了组件 F。 则组件 F 只能用在组件 A 中;不能被用在组件 C 中。

全局组件:

在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件

image-20230312210651169

6.6props

props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性。

<script>
export default {
    props:['init','自定义属性2'],
    data() {
        return {}
    },
};
</script>

vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值。否则会直接报错。

可以把props的值转存到data中

data(){
	count:return this.init
}

8-3 生命周期&数据共享

1.生命周期&生命周期函数

2.组件之间的数据共享

  • 父子共享

    • 父->子(自定义属性)

      image-20230313105124759

      类似与props里面是指针。

    • 子->父(自定义事件)

      image-20230313105146633

  • 兄弟共享(EventBus)

    ① 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象

    ② 在数据发送方,调用 bus.$emit(‘事件名称’, 要发送的数据) 方法触发自定义事件

    ③ 在数据接收方,调用 bus.$on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件

    image-20230313105218592

3.ref引用

ref 用来辅助开发者在不依赖于 jQuery 的情况下,获取 DOM 元素或组件的引用。

每个 vue 的组件实例上,都包含一个 $refs 对象,里面存储着对应的DOM 元素或组件的引用。默认情况下, 组件的 $refs 指向一个空对象。

3.1引用dom元素

<h1 ref="myh3">ref引用dom元素</h1>
this.$refs.myh3.style.color='red'

ps:引用组件实例也可以用此方法。

3.2引用组件实例

<my-counter ref="counterRef"></my-counter>
methods:{
    getRef(){
        console.log(this.$refs.counterRef)//可以使用组件实例
		this.$refs.counterRef.add()//也可以调用组件上的methods方法
    }
}

3.3控制文本框和按钮的按需切换

image-20230313104328845

3.4文本框自动获得焦点

当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref 引用,并调用原生 DOM 对象的 .focus() 方法即可。

image-20230313104624372

3.5this.$nextTick(cb) 方法

组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。

通俗的理解是:等组件的 DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素。

image-20230313105033995

8-4 动态组件 & 插槽 & 自定义指令

1.动态组件

动态组件指的是动态切换组件的显示与隐藏。

1.1动态组件渲染

vue提供了一个内置的组件,专门用来实现动态组件的渲染。

<component is="组件名称"></component>

<!--例-->
<component :is="comName"></component>
<script>
    data(){
        return comName:"Left"
    }
</script>

1.2使用keep-alive保持状态

默认情况下,切换动态组件时无法保持组件的状态。(data值等)

<keep-alive>
    <component is="组件名称"></component>
</keep-alive>

1.3keep-alive对应的生命周期函数

组件第一次创建:createdactivated都会被触发

组件被缓存:自动触发deactivated生命周期函数

组件被激活:自动触发activated生命周期函数

组件被销毁:destoyed

<script>
export default{
	created(){ console.log('创建') },
	destroyed(){ console.log('销毁') },

	activated(){ console.log('激活') },
	deactivated(){ console.log('缓存') }
}
</script>

lifecycle

1.4keep-alive的include/exclude属性

include 属性用来指定:只有名称匹配的组件会被缓存。(默认keep-alive包裹的所有组件都会被缓存)

多个组件名之间使用英文的逗号分隔。

<keep-alive include="Left,Right">
    <component :is="comName"></component>
</keep-alive>

exclude属性则表示排除项,include/exclude不能同时使用。

2.插槽

插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的 部分定义为插槽。

2.1插槽基础

在封装组件时,可以通过元素定义插槽,从而为用户预留内容占位符。

image-20230315181828430

  • 如果在封装组件时没有预留任何插槽,则用户提供的任何自定义内容都会被丢弃。

    image-20230315182042982

  • 封装组件时,可以为预留的 插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。

    image-20230315182101227

2.2具名插槽

如果在封装组件时需要预留多个插槽节点,则需要为每个插槽指定具体的 name 名称(属性)。这种带有具体名称的插槽叫做“具名插槽”。

在向具名插槽提供内容的时候,我们可以在一个元素上使用v-lot指令提供名称,也可以简写为#

<slot name="content"></slot>


<template v-lot=content>
	<h3>内容</h3>
</template>

<template #content>
	<h3>内容</h3>
</template>

如果没有指定名称,则所有插槽都会显示用户自定义内容。

2.3作用域插槽

在封装组件的过程中,可以为预留的 插槽绑定 props 数据,这种带有 props 数据的 叫做“作用域插槽”

<tbody>
    	<slot v-for="item in list" :user="item"></slot>
</tbody>

可以使用 v-slot: 的形式,接收作用域插槽对外提供的数据。scope是形参,没有意义。

image-20230315183426806

2.4结构插槽

作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程。

image-20230315190251396

3.自定义指令

vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。除此之外 vue 还允许开发者自定义指令。

3.1定义私有自定义指令(directives节点)

定义:

<script>
    export default{
        directives:{
            color:{
                bind(el){
                    el.style.color="red"
                }
            }
        },
    }
</script>

3.2使用自定义指令

使用:在使用自定义指令时,需要加上 v- 前缀

<h1 v-color>
    红色
</h1>

//动态绑定参数值
data(){
	return{
	color:"red"
 }
}
<h1 v-color="color">
    红色
</h1>

3.3通过binding获取指令的参数值

在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值:

directives:{
	color:{
		bind(el.binding){
			el.style.color=binding.value
		}
	}
}

3.4update函数

bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发。 update 函 数会在每次 DOM 更新时被调用。

image-20230315190918594

如果 insert 和update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:

image-20230315191059046

3.5全局自定义指令

全局共享的自定义指令需要通过“Vue.directive()”进行声明

image-20230315190857069

8-5 路由

1.前端路由

Hash 地址与组件之间的对应关系。

1.1工作方式

image-20230314180837161

2.vue-router的基本用法

① 安装 vue-router 包

npm i vue-router@3.5.2 -S

② 创建路由模块

​ 在 src 源代码目录下,新建 router/index.js 路由模块,并初始化如下的代码:

//路由模块

//1.导包
import Vue from 'vue'
import VueRouter  from 'vue-router'

//2.调用Vue.use()函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)

//3.创建路由实例对象
const router=new VueRouter()

//4.向外共享路由实例对象
export default router

③ 导入并挂载路由模块

​ 在 src/main.js 入口文件中,导入并挂载路由模块

import Vue from 'vue'
import App from './App.vue'

//导入路由模块
import router from './router'


Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  //2.挂载路由模块
  router:router
}).$mount('#app')

④ 声明路由链接和占位符

​ 在 src/App.vue 组件中,使用 vue-router 提供的 和 声明路由链接和占位符

//3.创建路由实例对象
const router=new VueRouter({
    routes:[//声明路由的匹配规则
        //path(要匹配的hash地址):component(要展示的路由组件)
        {path:'/home',component:Home},
        {path:'/movie',component:Movie}
    ]
})

3.vue-router 的常见用法

3.1路由重定向

​ 用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。

​ 通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向

//3.创建路由实例对象
const router=new VueRouter({
    routes:[//声明路由的匹配规则
        //当用户访问/的时候,跳转到/home对应的路由规则
        {path:'/',redirect:'/home'}
        //path(要匹配的hash地址):component(要展示的路由组件)
        {path:'/home',component:Home},
        {path:'/movie',component:Movie}
    ]
})

3.2嵌套路由

​ 通过路由实现组件的嵌套展示,叫做嵌套路由(右)。

image-20230317102731356

3.3子路由链接和子路由占位符

在 About.vue 组件中,声明 tab1 和 tab2 的子路由链接以及子路由占位符:

image-20230317111550103

在 src/router/index.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则:

image-20230317103039116

3.4动态路由匹配

动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。 在 vue-router 中使用英文的冒号(:)来定义路由的参数项。

image-20230317111451793

  • 可以使用 this.$route.params 对象访问到动态匹配的参数值

在这里插入图片描述

  • vue-router 允许在路由规则中开启 props 传参。

    image-20230317103906504

3.5声明式导航 & 编程式导航

在浏览器中,点击链接实现导航的方式,叫做声明式导航

​ 普通网页中点击 链接、vue 项目中点击 都属于声明式导航

在浏览器中,调用 API 方法实现导航的方式,叫做编程式导航

​ 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航

vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:

① this.$router.push(‘hash 地址’)

​ 跳转到指定 hash 地址,并增加一条历史记录

② this.$router.replace(‘hash 地址’)

​ 跳转到指定的 hash 地址,并替换掉当前的历史记录

③ this.$router.go(数值 n)

​ 实现导航历史前进、后退

this.$router.go简化:

① $router.back()

在历史记录中,后退到上一个页面

② $router.forward()

在历史记录中,前进到下一个页面

3.6 导航守卫

导航守卫可以控制路由的访问权限。

image-20230317104043720

3.6.1全局前置首位

每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,程序员可以对每个路由进行 访问权限的控制:

image-20230317105000785

3.6.2守卫方法的三个形参

image-20230317105056012

3.6.3next 函数的 3 种调用方式

image-20230317105126683

3.6.4控制后台主页的访问权限

image-20230317105145286

8-6 补充

1.在main.js中

import axios from axios
axios.defaults.baseURL='请求根路径'
Vue.prototype.$http=axios

请求时:

image-20230315193855690

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值