前端框架Vue笔记(二)

Vue路由

Vue Router是Vue.js的官方路由管理器。它与Vue.js核心深度集成,让构建单页面应用变得简单易行。Vue Router提供了一种声明式的路由方式,通过定义路由规则将URL映射到组件,实现组件的动态加载和切换。

以下是关于Vue Router的详细介绍:

  1. 安装Vue Router:

    • 通过npm安装Vue Router:

      npm install vue-router
      
      
    • 在项目中引入并使用Vue Router:

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      
      Vue.use(VueRouter)
      
      
  2. 定义路由规则:

    • 创建一个路由配置对象,定义路由规则。

    • 每个路由规则包含路径和对应的组件。

      const routes = [
        { path: '/', component: Home },
        { path: '/about', component: About },
        { path: '/user/:id', component: User }
      ]
      
      
  3. 创建路由实例:

    • 使用VueRouter构造函数创建路由实例,并传入路由配置对象。

      const router = new VueRouter({
        routes
      })
      
      
  4. 挂载路由实例:

    • 在创建Vue实例时,将路由实例挂载到Vue实例上。

      new Vue({
        router,
        render: h => h(App)
      }).$mount('#app')
      
      
  5. 路由出口:

    • 在组件模板中使用<router-view>组件作为路由出口,用于渲染匹配的路由组件。

      <template>
        <div>
          <router-view></router-view>
        </div>
      </template>
      
      
  6. 导航链接:

    • 使用<router-link>组件创建导航链接,通过to属性指定目标路由。

      <router-link to="/">Home</router-link>
      <router-link to="/about">About</router-link>
      
      
  7. 动态路由匹配:

    • 通过在路由路径中使用动态参数,实现动态路由匹配。

    • 在组件中可以通过$route.params访问动态参数的值。

      const routes = [
        { path: '/user/:id', component: User }
      ]
      
      
      <template>
        <div>
          <p>User ID: {{ $route.params.id }}</p>
        </div>
      </template>
      
      
  8. 嵌套路由:

    • 通过在路由配置中使用children属性,实现嵌套路由。

    • 在父组件中使用<router-view>组件作为子路由的出口。

      const routes = [
        {
          path: '/user/:id',
          component: User,
          children: [
            { path: 'profile', component: UserProfile },
            { path: 'posts', component: UserPosts }
          ]
        }
      ]
      
      
  9. 编程式导航:

    • 通过在组件中使用$router对象的方法,实现编程式导航。

    • 常用的方法包括pushreplacego等。

      this.$router.push('/about')
      this.$router.replace('/user/123')
      this.$router.go(-1)
      
      
  10. 路由守卫:

    • 通过路由守卫可以在路由导航过程中执行一些逻辑,如权限验证、数据获取等。

    • 常用的路由守卫包括全局守卫、路由独享守卫和组件内守卫。

      router.beforeEach((to, from, next) => {
        // 全局前置守卫
        // ...
        next()
      })
      
      const routes = [
        {
          path: '/user/:id',
          component: User,
          beforeEnter: (to, from, next) => {
            // 路由独享守卫
            // ...
            next()
          }
        }
      ]
      
      // 组件内守卫
      beforeRouteEnter(to, from, next) {
        // ...
        next()
      },
      beforeRouteUpdate(to, from, next) {
        // ...
        next()
      },
      beforeRouteLeave(to, from, next) {
        // ...
        next()
      }
      
      

混入

混入 (Mixin) 是 Vue 提供的一种组件复用机制,它允许你将一些通用的逻辑、数据和方法提取到单独的对象中,然后在多个组件之间共享。混入可以帮助你避免重复编写相同的代码,提高代码的可重用性和可维护性。

  1. 定义混入:

    • 创建一个包含通用选项的对象,如数据、方法、生命周期钩子等。

      const myMixin = {
        data() {
          return {
            message: 'Hello from mixin!'
          }
        },
        methods: {
          sayHello() {
            console.log('Hello from mixin method!')
          }
        },
        created() {
          console.log('Mixin created!')
        }
      }
      
      
  2. 使用混入:

    • 在组件中使用 mixins 选项来引入混入对象。

    • 可以将多个混入对象放入一个数组中。

      const MyComponent = {
        mixins: [myMixin],
        // 组件的其他选项...
      }
      
      
  3. 选项合并:

    • 当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行"合并"。

    • 数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

    • 同名钩子函数将合并为一个数组,因此都将被调用。混入对象的钩子将在组件自身钩子之前调用。

    • 值为对象的选项,如 methodscomponentsdirectives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

      const mixin = {
        data() {
          return {
            message: 'Hello from mixin!',
            foo: 'abc'
          }
        },
        created() {
          console.log('Mixin created!')
        }
      }
      
      const MyComponent = {
        mixins: [mixin],
        data() {
          return {
            message: 'Hello from component!',
            bar: 'def'
          }
        },
        created() {
          console.log('Component created!')
        }
      }
      
      // 最终的数据将是:
      // {
      //   message: 'Hello from component!',
      //   foo: 'abc',
      //   bar: 'def'
      // }
      
      // 最终的钩子函数执行顺序:
      // Mixin created!
      // Component created!
      
      
  4. 全局混入:

    • 可以使用 Vue.mixin() 方法全局注册一个混入对象。

    • 一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。

      Vue.mixin({
        created() {
          console.log('Global mixin created!')
        }
      })
      
      const app = new Vue({
        // ...
      })
      
      // 输出: Global mixin created!
      
      
  5. 自定义选项合并策略:

    • 自定义选项将使用默认策略,即简单地覆盖已有值。

    • 如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数。

      Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
        // 返回合并后的值
      }
      
      
  6. 混入的注意事项:

    • 混入对象可以包含任意的组件选项,包括数据、方法、生命周期钩子等。
    • 当组件和混入对象含有同名选项时,会进行合并。
    • 谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例。
    • 如果多个混入对象存在同名选项,则选项将按照数组中的顺序进行合并,后面的选项将覆盖前面的选项。

插件

插件 (Plugin) 是 Vue 提供的一种扩展机制,它可以增强 Vue 的功能,并提供可复用的解决方案。插件可以是一个包含 install 方法的对象,也可以是一个函数。通过使用插件,可以全局地添加组件、指令、过滤器、混入等,或者扩展 Vue 的原型方法。

  1. 定义插件:

    • 创建一个包含 install 方法的对象,或者直接定义一个函数作为插件。

    • install 方法接收 Vue 构造器和一个可选的选项对象作为参数。

      const myPlugin = {
        install(Vue, options) {
          // 插件的安装逻辑...
        }
      }
      
      // 或者定义一个函数作为插件
      function myPlugin(Vue, options) {
        // 插件的安装逻辑...
      }
      
      
  2. 安装插件:

    • 使用 Vue.use() 方法全局安装插件。

    • 插件应该在创建 Vue 实例之前安装。

      Vue.use(myPlugin)
      
      // 或者传入选项对象
      Vue.use(myPlugin, { /* 选项 */ })
      
      
  3. 添加全局资源:

    • 在插件的 install 方法中,可以全局注册组件、指令、过滤器等。

      const myPlugin = {
        install(Vue) {
          // 注册全局组件
          Vue.component('my-component', {
            // 组件选项...
          })
      
          // 注册全局指令
          Vue.directive('my-directive', {
            // 指令选项...
          })
      
          // 注册全局过滤器
          Vue.filter('my-filter', function (value) {
            // 过滤器逻辑...
          })
        }
      }
      
      
  4. 扩展 Vue 原型:

    • 在插件中,可以通过扩展 Vue 的原型来添加全局可用的方法。

      const myPlugin = {
        install(Vue) {
          // 添加实例方法
          Vue.prototype.$myMethod = function () {
            // 方法逻辑...
          }
        }
      }
      
      
  5. 插件的选项对象:

    • 在安装插件时,可以传入一个选项对象来配置插件的行为。

    • 插件可以根据选项对象的值来调整其功能。

      const myPlugin = {
        install(Vue, options) {
          // 根据选项配置插件行为
          if (options.someOption) {
            // 执行相应的逻辑...
          }
        }
      }
      
      Vue.use(myPlugin, { someOption: true })
      
      
  6. 插件的作用域:

    • 插件的作用域是全局的,一旦安装,它将影响每一个 Vue 实例。
    • 因此,插件应该谨慎地使用全局资源和修改 Vue 原型。
  7. 插件的执行顺序:

    • 如果使用多个插件,它们将按照安装的顺序依次执行。
    • 插件的 install 方法将按照安装顺序依次调用。

插件是 Vue 生态系统中的重要组成部分,它提供了一种灵活的方式来扩展 Vue 的功能和行为。通过插件,可以封装和分发可复用的功能模块,如状态管理、路由、表单验证、国际化等。

在实际开发中,插件可以用于以下场景:

  • 封装通用的组件库,如 UI 组件、图表组件等。
  • 集成第三方库或服务,如 axios、vue-router、vuex 等。
  • 添加全局的功能和行为,如全局过滤器、自定义指令等。
  • 扩展 Vue 的原型方法,提供全局可用的工具函数。

状态管理

状态管理是指对应用程序中的数据进行有效的组织、管理和共享,以便在组件之间保持数据的一致性和可预测性。在 Vue 应用中,随着应用规模的增长和组件数量的增加,手动管理和同步组件之间的状态变得越来越困难。这时候,就需要使用状态管理模式来解决这个问题。

Vuex 是 Vue 官方提供的状态管理库,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

  1. 状态管理的概念:

    • 状态 (State): 应用程序中的数据,可以是组件内部的数据或共享的数据。
    • 视图 (View): 用户界面,根据当前的状态进行渲染。
    • 操作 (Actions): 用户的交互行为或异步操作,如点击按钮、发送请求等,可以触发状态的变化。
  2. Vuex 的核心概念:

    • Store: 状态容器,用于存储应用的状态。每个 Vue 应用只有一个 Store 实例。
    • State: 状态对象,包含了应用的数据。通过 this.$store.state 访问。
    • Getters: 状态的计算属性,用于从 State 中派生出一些新的数据。通过 this.$store.getters 访问。
    • Mutations: 状态的同步变更操作。通过 this.$store.commit() 提交 Mutations。
    • Actions: 异步操作或复杂逻辑,可以包含多个 Mutations。通过 this.$store.dispatch() 分发 Actions。
    • Modules: 将 Store 分割成模块,每个模块拥有自己的 State、Getters、Mutations 和 Actions。
  3. 创建 Vuex Store:

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      state: {
        count: 0
      },
      getters: {
        doubleCount(state) {
          return state.count * 2
        }
      },
      mutations: {
        increment(state) {
          state.count++
        }
      },
      actions: {
        incrementAsync({ commit }) {
          setTimeout(() => {
            commit('increment')
          }, 1000)
        }
      }
    })
    
    export default store
    
    
  4. 在组件中使用 Vuex:

    import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
    
    export default {
      computed: {
        ...mapState(['count']),
        ...mapGetters(['doubleCount'])
      },
      methods: {
        ...mapMutations(['increment']),
        ...mapActions(['incrementAsync'])
      }
    }
    
    
  5. 模块化:

    • 当应用变得复杂时,可以将 Store 分割成模块,每个模块拥有自己的状态、Getters、Mutations 和 Actions。
    • 通过 modules 选项定义模块,每个模块都是一个独立的状态树。
    const moduleA = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    
  6. 插件:

    • Vuex 提供了插件机制,可以在 Store 实例化时应用插件。
    • 插件可以监听 Mutations 的提交,执行自定义的逻辑,如日志记录、状态持久化等。
    const myPlugin = store => {
      store.subscribe((mutation, state) => {
        // 每次 Mutation 之后调用
        // mutation 的格式为 { type, payload }
      })
    }
    
    const store = new Vuex.Store({
      // ...
      plugins: [myPlugin]
    })
    
    
  7. 严格模式:

    • 在严格模式下,无论何时发生了状态变更且不是由 Mutation 函数引起的,将会抛出错误。
    • 这可以保证所有的状态变更都能被调试工具跟踪到。
    const store = new Vuex.Store({
      // ...
      strict: true
    })
    
    

状态管理是大型 Vue 应用必不可少的部分,它可以帮助我们有效地组织和维护应用的状态,提高代码的可维护性和可扩展性。Vuex 提供了一套完整的状态管理解决方案,通过 Store、State、Getters、Mutations 和 Actions 等概念,使得状态的变化变得可预测和可追踪。

组件通信

组件通信是 Vue 应用中的重要概念,它指的是组件之间如何传递数据和触发事件。在 Vue 中,组件是独立的、可复用的代码块,每个组件都有自己的数据和行为。为了使组件能够协同工作,我们需要建立组件之间的通信机制。

Vue 提供了多种组件通信的方式:

  1. 父子组件通信:

    • 父组件通过 props 向子组件传递数据。
    • 子组件通过 $emit 触发事件,向父组件传递数据。
    <!-- 父组件 -->
    <template>
      <child-component :message="parentMessage" @child-event="handleChildEvent"></child-component>
    </template>
    
    <script>
    export default {
      data() {
        return {
          parentMessage: 'Hello from parent'
        }
      },
      methods: {
        handleChildEvent(data) {
          console.log('Received data from child:', data)
        }
      }
    }
    </script>
    
    <!-- 子组件 -->
    <template>
      <div>
        <p>{{ message }}</p>
        <button @click="emitEvent">Emit Event</button>
      </div>
    </template>
    
    <script>
    export default {
      props: ['message'],
      methods: {
        emitEvent() {
          this.$emit('child-event', 'Data from child')
        }
      }
    }
    </script>
    
    
  2. 非父子组件通信:

    • 使用事件总线 (Event Bus) 进行通信。
    • 通过一个空的 Vue 实例作为事件总线,用于触发事件和监听事件。
    // 事件总线
    const eventBus = new Vue()
    
    // 组件 A
    export default {
      methods: {
        sendData() {
          eventBus.$emit('event-bus', 'Data from A')
        }
      }
    }
    
    // 组件 B
    export default {
      created() {
        eventBus.$on('event-bus', data => {
          console.log('Received data from A:', data)
        })
      }
    }
    
    
  3. 使用 Vuex 进行状态管理:

    • Vuex 是 Vue 的官方状态管理库,用于集中管理应用的状态。
    • 通过 Vuex 的 state、getters、mutations 和 actions 来管理和修改状态。
    • 组件可以通过 this.$store 访问 Vuex 的 store 实例。
  4. 使用 provide/inject 进行跨级通信:

    • 父组件通过 provide 选项提供数据。
    • 子组件通过 inject 选项注入数据。
    // 父组件
    export default {
      provide: {
        sharedData: 'Hello from parent'
      }
    }
    
    // 子组件
    export default {
      inject: ['sharedData'],
      created() {
        console.log('Received data from parent:', this.sharedData)
      }
    }
    
    
  5. 使用 $refs 访问子组件实例:

    • 父组件通过 ref 属性给子组件设置引用名。
    • 父组件通过 this.$refs 访问子组件实例,并调用子组件的方法或访问子组件的数据。
    <!-- 父组件 -->
    <template>
      <child-component ref="child"></child-component>
    </template>
    
    <script>
    export default {
      mounted() {
        this.$refs.child.childMethod()
      }
    }
    </script>
    
    <!-- 子组件 -->
    <script>
    export default {
      methods: {
        childMethod() {
          console.log('Child method called')
        }
      }
    }
    </script>
    
    
  6. 使用 $parent 和 $children 访问父组件和子组件实例:

    • 子组件通过 this.$parent 访问父组件实例。
    • 父组件通过 this.$children 访问子组件实例数组。
    • 注意: 这种方式不太推荐,因为它增加了组件之间的耦合度。
  7. 使用插槽 (Slots) 进行内容分发:

    • 父组件通过 <slot> 元素定义插槽。
    • 子组件通过 <slot> 元素接收和渲染父组件传递的内容。
    <!-- 父组件 -->
    <template>
      <child-component>
        <h1>Hello from parent</h1>
        <p>This is some content from parent</p>
      </child-component>
    </template>
    
    <!-- 子组件 -->
    <template>
      <div>
        <slot></slot>
      </div>
    </template>
    
    

动画和过渡

在 Vue 中,动画和过渡效果可以为应用添加视觉吸引力和交互体验。Vue 提供了内置的过渡系统,使得在元素或组件进入、离开或更新时应用动画效果变得简单和直观。

Vue 的过渡系统主要基于以下几个概念:

  1. 过渡组件:
    • <transition>: 用于给单个元素或组件添加进入/离开过渡效果。
    • <transition-group>: 用于给一个列表中的元素添加进入/离开过渡效果。
  2. 过渡的类名:
    • v-enter: 定义进入过渡的开始状态。
    • v-enter-active: 定义进入过渡生效时的状态。
    • v-enter-to: 定义进入过渡的结束状态。
    • v-leave: 定义离开过渡的开始状态。
    • v-leave-active: 定义离开过渡生效时的状态。
    • v-leave-to: 定义离开过渡的结束状态。
  3. 过渡的钩子函数:
    • before-enter: 在元素被插入到 DOM 之前触发。
    • enter: 在元素被插入到 DOM 之后的下一帧触发。
    • after-enter: 在 enter 过渡完成后触发。
    • before-leave: 在离开过渡开始时触发。
    • leave: 在离开过渡开始后的下一帧触发。
    • after-leave: 在 leave 过渡完成后触发。

下面是一些示例代码,展示了如何使用 Vue 的过渡系统:

  1. 单元素过渡:

    <template>
      <div>
        <button @click="show = !show">Toggle</button>
        <transition name="fade">
          <p v-if="show">Hello, Vue!</p>
        </transition>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          show: true
        }
      }
    }
    </script>
    
    <style>
    .fade-enter-active, .fade-leave-active {
      transition: opacity 0.5s;
    }
    .fade-enter, .fade-leave-to {
      opacity: 0;
    }
    </style>
    
    
  2. 列表过渡:

    <template>
      <div>
        <button @click="addItem">Add Item</button>
        <transition-group name="list" tag="ul">
          <li v-for="item in items" :key="item">{{ item }}</li>
        </transition-group>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          items: [1, 2, 3]
        }
      },
      methods: {
        addItem() {
          const newItem = Math.max(...this.items) + 1
          this.items.push(newItem)
        }
      }
    }
    </script>
    
    <style>
    .list-enter-active, .list-leave-active {
      transition: all 0.5s;
    }
    .list-enter, .list-leave-to {
      opacity: 0;
      transform: translateX(30px);
    }
    </style>
    
    
  3. 使用钩子函数:

    <template>
      <div>
        <button @click="show = !show">Toggle</button>
        <transition
          @before-enter="beforeEnter"
          @enter="enter"
          @after-enter="afterEnter"
          @before-leave="beforeLeave"
          @leave="leave"
          @after-leave="afterLeave"
        >
          <p v-if="show">Hello, Vue!</p>
        </transition>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          show: true
        }
      },
      methods: {
        beforeEnter(el) {
          console.log('Before Enter')
        },
        enter(el, done) {
          console.log('Enter')
          done()
        },
        afterEnter(el) {
          console.log('After Enter')
        },
        beforeLeave(el) {
          console.log('Before Leave')
        },
        leave(el, done) {
          console.log('Leave')
          done()
        },
        afterLeave(el) {
          console.log('After Leave')
        }
      }
    }
    </script>
    
    

除了使用过渡组件和类名,Vue 还提供了以下几种方式来创建动画效果:

  1. 使用 CSS 动画:
    • 通过 CSS 的 @keyframes 规则定义动画关键帧。
    • 在过渡类名中应用 CSS 动画。
  2. 使用 JavaScript 钩子函数:
    • 在过渡钩子函数中使用 JavaScript 操作 DOM 元素来创建动画效果。
    • 可以与第三方动画库 (如 Velocity.js、GreenSock 等) 结合使用。
  3. 使用第三方 CSS 动画库:
    • 使用 Animate.css 等流行的 CSS 动画库提供的预设动画类。
    • 将动画类应用于过渡组件的类名。

服务端渲染

服务端渲染 (Server-Side Rendering, SSR) 是指在服务器端将 Vue 组件渲染为 HTML 字符串,并将其发送给浏览器,然后在浏览器端进行混合 (hydration) 的过程。与传统的客户端渲染 (Client-Side Rendering, CSR) 不同,SSR 可以提供更好的首屏加载速度、SEO 友好性和更好的用户体验。

以下是关于 Vue 服务端渲染的详细解释:

  1. 服务端渲染的原理:

    • 在服务器端,通过 Vue 的 vue-server-renderer 包将 Vue 组件渲染为 HTML 字符串。
    • 服务器将渲染好的 HTML 字符串发送给浏览器。
    • 浏览器接收到 HTML 后,直接显示出来,无需等待 JavaScript 加载和执行。
    • 浏览器加载并执行 JavaScript 后,Vue 会在客户端进行混合,将事件绑定到已渲染的 HTML 上。
  2. 服务端渲染的优点:

    • 更好的首屏加载速度:服务器端渲染的 HTML 可以立即显示,无需等待 JavaScript 加载和执行。
    • SEO 友好性:搜索引擎可以直接抓取服务器端渲染的 HTML,有利于 SEO。
    • 更好的用户体验:用户可以更快地看到内容,提升了用户体验。
  3. 服务端渲染的实现步骤:

    • 安装所需的依赖:

      npm install vue vue-server-renderer express
      
      
    • 创建一个 Vue 实例:

      const Vue = require('vue')
      const app = new Vue({
        template: `<div>Hello, {{ message }}</div>`,
        data: {
          message: 'Vue SSR'
        }
      })
      
      
    • 创建一个 Express 服务器:

      const express = require('express')
      const server = express()
      
      
    • 使用 vue-server-renderer 将 Vue 实例渲染为 HTML:

      const renderer = require('vue-server-renderer').createRenderer()
      
      server.get('*', (req, res) => {
        renderer.renderToString(app, (err, html) => {
          if (err) {
            res.status(500).end('Internal Server Error')
            return
          }
          res.send(`
            <!DOCTYPE html>
            <html lang="en">
              <head>
                <title>Vue SSR</title>
              </head>
              <body>
                ${html}
              </body>
            </html>
          `)
        })
      })
      
      
    • 启动服务器:

      server.listen(8080, () => {
        console.log('Server is running at <http://localhost:8080>')
      })
      
      
  4. 服务端渲染的注意事项:

    • 服务端渲染只支持 beforeCreate 和 created 生命周期钩子,不支持 beforeMount、mounted 等客户端特有的钩子。
    • 服务端渲染时,不能访问浏览器特定的 API,如 window、document 等。
    • 需要特别处理一些第三方库的兼容性问题,确保它们在服务端和客户端都能正常工作。
  5. 使用 Nuxt.js 简化服务端渲染:

    • Nuxt.js 是一个基于 Vue.js 的高级框架,简化了服务端渲染的开发过程。
    • Nuxt.js 提供了开箱即用的服务端渲染功能,自动处理了许多底层细节。
    • 通过 Nuxt.js,我们可以更轻松地构建服务端渲染的 Vue 应用。
  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值