Vue 2 项目和插件使用

2 篇文章 0 订阅
1 篇文章 0 订阅

目录

Less

ElementUI

CDN

NPM

        完整引入

        按需引入

        全局配置

Vant    

CDN

NPM

        自动按需引入 (推荐)

        手动按需引入

        导入所有组件

vuex(store)

iconfont

font-class 引用

Symbol 引用

vue-clipboard2

vue-scroller

vue-quill-editor

sass-resources-loader

qrcodejs2

vue-cropper


Less

        Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。

        安装依赖(less less-loader):

cnpm install less less-loader --save-dev

        安装好之后,如果报如下错误:“TypeError: this.getOptions is not a function”。 出现这个错误的原因是 less-loader 安装版本过高,最快的解决办法是重新安装较低的 less-loader 版本。

// 卸载当前安装的 less-loader
cnpm uninstall less-loader
// 安装低版本的 less-loader, 例如5.0.0版本
cnpm install less-loader@5.0.0 --save-dev

        具体在 Vue 项目中使用:

<style lang="less" scoped>
    ...less here
</style>

ElementUI

CDN

        目前可以通过 unpkg.com/element-ui 获取到最新版本的资源,在页面上引入 js css 文件即可开始使用。

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

NPM

        推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。

npm i element-ui -S

        使用 Element :可以引入整个 Element,或是根据需要仅引入部分组件。

        完整引入

        main.js 中写入以下内容,需要注意的是,样式文件需要单独引入。

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

        按需引入

        借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。首先,安装 babel-plugin-component

npm install babel-plugin-component -D

        然后,将 .babelrc 修改为:

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

        接下来,如果你只希望引入部分组件,比如 Button,那么需要在 main.js 中写入以下内容:

import Vue from 'vue';
import { Button } from 'element-ui';
import App from './App.vue';

Vue.component(Button.name, Button);
/* 或写为
 * Vue.use(Button)
 */
new Vue({
  el: '#app',
  render: h => h(App)
});

        全局配置

        引入 Element 时可以传入一个全局配置对象。该对象目前支持 size 与 zIndex 字段。size 用于改变组件的默认尺寸,zIndex 设置弹框的初始 z-index(默认值:2000)。按照引入 Element 的方式,具体操作如下: 

        完整引入 Element

import Vue from 'vue';
import Element from 'element-ui';
Vue.use(Element, { size: 'small', zIndex: 3000 });

        按需引入 Element

import Vue from 'vue';
import { Button } from 'element-ui';

Vue.prototype.$ELEMENT = { size: 'small', zIndex: 3000 };
Vue.use(Button);

Vant    

        Vant 是一个轻量、可靠的移动端组件库,于 2017 年开源。

        目前 Vant 官方提供了 Vue 2 版本Vue 3 版本微信小程序版本,并由社区团队维护 React 版本支付宝小程序版本

CDN

        使用 Vant 最简单的方法是直接在 html 文件中引入 CDN 链接,之后你可以通过全局变量 Vant 访问到所有组件。

<!-- 引入样式文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css"/>

<!-- 引入 Vue 和 Vant 的 JS 文件 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js"></script>

<script>
  // 在 #app 标签下渲染一个按钮组件
  new Vue({
    el: '#app',
    template: `<van-button>按钮</van-button>`,
  });

  // 调用函数组件,弹出一个 Toast
  vant.Toast('提示');

  // 通过 CDN 引入时不会自动注册 Lazyload 组件
  // 可以通过下面的方式手动注册
  Vue.use(vant.Lazyload);
</script>

NPM

        通过 npm 安装,在现有项目中使用 Vant 时,可以通过 npm yarn 进行安装:

# Vue 3 项目, 安装最新版 Vant:
npm i vant -S

# Vue 2 项目, 安装 Vant 2:
npm i vant@latest-v2 -S

        引入组件有以下三种方式:

        自动按需引入 (推荐)

        babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。首先,安装  babel-plugin-import

# 安装插件
npm i babel-plugin-import -D

        然后在 .babelrc 中添加配置:

// 注意:webpack 1 无需设置 libraryDirectory
{
  "plugins": [
    ["import", {
      "libraryName": "vant",
      "libraryDirectory": "es",
      "style": true
    }]
  ]
}

// 对于使用 babel7 的用户,可以在 babel.config.js 中配置
module.exports = {
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant']
  ]
};

        接着可以在代码中直接引入 Vant 组件,插件会自动将代码转化为方式二中的按需引入形式。

        手动按需引入

        在不使用插件的情况下,可以手动引入需要的组件,以 Button 为例。

import Button from 'vant/lib/button';
import 'vant/lib/button/style';

        导入所有组件

        Vant 支持一次性导入所有组件,引入所有组件会增加代码包体积,因此不推荐这种做法。

import Vue from 'vue';
import Vant from 'vant';
import 'vant/lib/index.css';

Vue.use(Vant);

vuex(store)

        vuex 中的 store 是一个状态管理工具,用于单个页面中不同组件(例如兄弟组件)的数据流通。它使用单一状态——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 ”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。

        npm 安装 vuex

npm install vuex --save

        然后在项目的 src 文件目录下创建 store 文件夹,在 store 文件夹中创建一个 js 文件,例如:index.js

        1、创建 store 实例,在新创建的 js 文件中加入如下代码:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    // store 状态的保存
    bankName: "中央银行"
  },
  mutations: {
    // store 状态的修改
    newBankName(state, msg) {
      state.bankName = msg
    }
  },
  actions: {
  },
  modules: {
  }
})

export default store

         2、在全局 main.js 引入 store,这样所有的组件都可以使用 store 中的数据了。

// main.js 文件
import Vue from 'vue'
import App from './App.vue'
import store from './store'

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

        3、使用 $store.state.xxx 调用我们保存的数据。例如使用计算属性返回 store 中的数据:

export default {
  ...
  computed: {
    bankName() {
      return this.$store.state.bankName
    }
  },
  ...
}

        4、如果想在组件中修改 store 中的状态,可以使用 this.$store.commit() 方法。

export default {
  ...
  computed: {
    bankName() {
      return this.$store.state.bankName;
    }
  },
  methods: {
    newBankName: function() {
      this.$store.commit('newBankName', "工商银行")
    }
  }
 ...   
}

        通过调用 this.$store.commit() 方法修改 store 状态,store 中 bankName 的值就变成了“工商银行”,同时所有用到过 bankName 的地方也将同步更新。

iconfont

        应用中图标的显示是必不可少的,如果每个图标都用图片,那样会使得文件占用资源很大,可以用 iconfont 来显示图标,占用更少资源。

        iconfont 官网:iconfont-阿里巴巴矢量图标库 ,先注册账号,然后搜索自己想要的图标,将想要的图标添加入库(选择第一个“购物车”图标按钮):

 添加后,点击右上角的“购物车”,选择“下载代码”,最后将下载下来的 zip 包解压并添加到自己的 Vue 项目。

        在项目中使用 iconfont 主要有以下两种方式:

font-class 引用

        第一步:引入项目下面生成的 fontclass 代码:

<link rel="stylesheet" href="./iconfont.css">

        第二步:挑选相应图标并获取类名,应用于页面:

// xxx 表示图标名称,可在 iconfont.json 文件中的 “font_class” 属性查看
<span class="iconfont icon-xxx"></span>

Symbol 引用

        这是一种全新的使用方式,应该说这才是未来的主流,也是目前推荐的用法。这种用法其实是做了一个 SVG 的集合。

        第一步:引入项目下面生成的 symbol 代码:

<script src="./iconfont.js"></script>

        第二步:加入通用 CSS 代码(引入一次就行):

<style>
.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

        第三步:挑选相应图标并获取类名,应用于页面:

// xxx 表示图标名称,可在 iconfont.json 文件中的 “font_class” 属性查看
<svg class="icon" aria-hidden="true">
  <use xlink:href="#icon-xxx"></use>
</svg>

vue-clipboard2

        vue-clipboard2 插件支持复制内容至剪切板

        使用 npm 安装插件

npm install vue-clipboard2 --save

        在项目中引用

import Vue from 'vue'
import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard)

        引用后,具体在项目中使用有以下两种方式:

        方式一:

<template>
  <div>
    <input type="text" v-model="message" placeholder="请输入内容">
    <button v-clipboard:copy=message
            v-clipboard:success="onCopy"
            v-clipboard:error="onError">复制
    </button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      message: ''
    }
  },
  methods: {
    onCopy: function (e) {
      alert('You just copied: ' + e.text)
    },
    onError: function (e) {
      alert('Failed to copy texts')
    }
  }
}
</script>

        方式二 

<template>
  <div>
    <button @click="copyCode">复制</button>
  </div>
</template>

<script>
export default {
  methods: {
    copyCode () {
      this.$copyText('某些内容').then(
        res => {
          alert('已成功复制,可直接去粘贴!复制内容为:' + res.text)
        },
        err => {
          alert('复制失败,err:' + err)
        }
      )
    }
  }
}
</script>

vue-scroller

        vue-scroller 用于在页面中滚动,下拉刷新,上拉加载等功能。

        npm 安装 vue-scroller

npm i vue-scroller -S

        插件引入到项目

import Vue from 'vue'
import VueScroller from 'vue-scroller'
Vue.use(VueScroller)

        在项目中使用示例

<template>
  <div id="app">
    <scroller :on-refresh="refresh" :on-infinite="infinite" ref="my_scroller">
      <div v-for="(item, index) in items" :key="index">
        {{ item }}
      </div>
    </scroller>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: []
    }
  },
  
  mounted() {
    for (var i = 1; i <= 20; i++) {
      this.items.push(i + ' - 下拉刷新,上拉加载')
    }
    this.top = 1
    this.bottom = 20
  },

  methods: {
    refresh (done) {
      setTimeout(() => {
        var start = this.top - 1
        for (var i = start; i > start - 10; i--) {
          this.items.splice(0, 0, i + ' - 下拉刷新,上拉加载')
        }
        this.top = this.top - 10
        done()
      }, 1500)
    },

    infinite (done) {
      setTimeout(() => {
        var start = this.bottom + 1
        for (var i = start; i < start + 10; i++) {
          this.items.push(i + ' - 下拉刷新,上拉加载')
        }
        this.bottom = this.bottom + 10
        done()
      }, 1000)
    }
  }
}
</script>

        其他重要的属性:

refreshText    // 下拉加载的提示内容,默认值为:“下拉刷新”
noDataText     // 上拉刷新的提示内容,默认值为:“没有更多数据”

finishInfinite(true)    // 开始下拉加载
finishPullToRefresh()   // 停止下拉加载

// 开始/停止上拉刷新
// 当参数为false时,上拉获取数据可以重新调用。
// 当参数为true,上拉获取数据回调函数停止使用,上拉提示会显示 noDataText 属性的值
finishInfinite(isNoMoreData :Boolean)

vue-quill-editor

       传统的 textArea 输入框输入的内容没法做格式上的更改, vue-quill-editor 可以让我们像处理word 一样,可以对其中内容的格式做一些调整,还可以添加图片等等,它在开发中有个专有名词,叫富文本编辑器。

        由于 vue-quill-editor 依赖于 quill ,所以需要先安装 quill

npm install quill -S

        然后安装 vue-quill-editor 

npm install vue-quill-editor -S

        插件引入到项目

import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

        具体使用示例

<template>
  <div class="containerWrap">
    <quill-editor v-model="content"
                    ref="myQuillEditor"
                    :options="editorOption"
                    @ready="onEditorReady($event)"
                    @blur="onEditorBlur($event)"
                    @focus="onEditorFocus($event)"
                    @change="onEditorChange($event)">
    </quill-editor>
  </div>
</template>

<script>
export default {
  components: {
    quillEditor
  },
  data () {
    return {
      content: '编辑的文本',
      editorOption: {    // 自定义 toolbar 菜单
        placeholder: '请在这里输入',
        modules: {
          toolbar: [
            ['bold', 'italic', 'underline', 'strike'], // 加粗,斜体,下划线,删除线
            ['blockquote', 'code-block'], // 引用,代码块
            [{ 'header': 1 }, { 'header': 2 }], // 标题,键值对的形式;1、2表示字体大小
            [{'list': 'ordered'}, { 'list': 'bullet' }], // 列表
            [{'script': 'sub'}, { 'script': 'super' }], // 上下标
            [{'indent': '-1'}, { 'indent': '+1' }], // 缩进
            [{ 'direction': 'rtl' }], // 文本方向
            [{ 'size': ['small', false, 'large', 'huge'] }], // 字体大小
            [{ 'header': [1, 2, 3, 4, 5, 6, false] }], // 几级标题
            [{ 'color': [] }, { 'background': [] }], // 字体颜色,字体背景颜色
            [{ 'font': [] }], // 字体
            [{ 'align': [] }], // 对齐方式
            ['clean'], // 清除字体样式
            ['image', 'video'] // 上传图片、上传视频
          ]
        }
      }
    }
  },
  methods: {
    onEditorReady (editor) {
      // 准备编辑器
    },
    onEditorBlur () {}, // 失去焦点事件
    onEditorFocus () {}, // 获得焦点事件
    onEditorChange () {} // 内容改变事件
  }
}
</script>

sass-resources-loader

        我们经常用less定义一些全局变量,比如头部的高度,比如主题的颜色,比如侧边栏的宽度,这时我们定义less 全局文件是有必要的,可以使用插件 sass-resources-loader 。

        npm 安装 sass-resources-loader

npm install sass-resources-loader --save-dev

        vue-cli@2:在 buildutils.js 文件中第 42 行后面加上以下代码:

if (loader === 'less') {    // 如果是使用 sass,则将 'less' 改成 'sass' 即可
  loaders.push({
    loader: 'sass-resources-loader',
    options: {
      resources: [path.resolve(__dirname, 'path/to/your/file.less'),]
    },
  });
}

        vue-cli@3:在 vue.config.js​ 文件(如果没有就自行创建)中加入以下代码:

// vue.config.js
const path = require('path');//引入path模块
module.exports = {
  chainWebpack: config => {
    // 如果使用的是 sass,则 'less' 换成 'scss'
    const oneOfsMap = config.module.rule('less').oneOfs.store
    oneOfsMap.forEach(item => {
      item
        .use('sass-resources-loader')
        .loader('sass-resources-loader')
        .options({
          resources: ['path.resolve(__dirname, 'path/to/your/file.less')']
        })
        .end()
    })
  }
}

        修改完配置文件记得重启服务器。

qrcodejs2

        qrcodejs2 是用于生成 QRCode javascript 库。qrcodejs2 没有依赖项。

        npm 安装 qrcodejs2 

npm install qrcodejs2 --save-dev

        在项目中使用

<div id="qrcode"></div>

<script type="text/javascript">
import QRCode from 'qrcodejs2';    // 导入到项目
var qrcode = new QRCode(document.getElementById("qrcode"), {
	text: "http://jindo.dev.naver.com/collie",
    // 以下为一些配置,按需配置
	width: 128,
	height: 128,
	colorDark : "#000000",     //二维码颜色
	colorLight : "#ffffff",    //二维码背景色
	correctLevel : QRCode.CorrectLevel.H    //容错率,L/M/H
});
</script>

vue-cropper

       vue-cropper 是一个优雅的图片裁剪插件。

        npm 安装插件:

npm install vue-cropper --save

        在 vue 项目中引入插件:

// Vue2 组件内引入
import { VueCropper }  from 'vue-cropper' 
components: {
  VueCropper
}

// Vue2 全局引入
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)

        具体使用示例:

<template>
  <div class="cropper-content">
    <div class="cropper-box">
      <div class="cropper">
        <vue-cropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.outputSize"
            :outputType="option.outputType"
            :info="option.info"
            :canScale="option.canScale"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixed="option.fixed"
            :fixedNumber="option.fixedNumber"
            :full="option.full"
            :fixedBox="option.fixedBox"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :centerBox="option.centerBox"
            :height="option.height"
            :infoTrue="option.infoTrue"
            :maxImgSize="option.maxImgSize"
            :enlarge="option.enlarge"
            :mode="option.mode"
            @realTime="realTime"
            @imgLoad="imgLoad">
        </vue-cropper>
      </div>
      <!--底部操作工具按钮-->
      <div class="footer-btn">
        <div class="scope-btn">
          <label class="btn" for="uploads">选择封面</label>
          <input type="file" id="uploads" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="selectImg($event)">
          <el-button size="mini" type="danger" plain icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button>
          <el-button size="mini" type="danger" plain icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</el-button>
          <el-button size="mini" type="danger" plain @click="rotateLeft">↺ 左旋转</el-button>
          <el-button size="mini" type="danger" plain @click="rotateRight">↻ 右旋转</el-button>
        </div>
        <div class="upload-btn">
          <el-button size="mini" type="success" @click="uploadImg('base64')">上传封面 <i class="el-icon-upload"></i></el-button>
        </div>
      </div>
    </div>
    <!--预览效果图-->
    <div class="show-preview">
      <div :style="previews.div" class="preview">
        <img :src="previews.url" :style="previews.img">
      </div>
    </div>
  </div>
</template>
<script>
import { VueCropper } from 'vue-cropper'
export default {
  name: "CropperImage",
  components: {
    VueCropper
  },
  props:['Name'],
  data() {
    return {
      name:this.Name,
      previews: {},
      option:{
        img: '',             //裁剪图片的地址
        outputSize: 1,       //裁剪生成图片的质量(可选0.1 - 1)
        outputType: 'jpeg',  //裁剪生成图片的格式(jpeg || png || webp)
        info: true,          //图片大小信息
        canScale: true,      //图片是否允许滚轮缩放
        autoCrop: true,      //是否默认生成截图框
        autoCropWidth: 210,  //默认生成截图框宽度
        autoCropHeight: 210, //默认生成截图框高度
        fixed: true,         //是否开启截图框宽高固定比例
        fixedNumber: [1, 1], //截图框的宽高比例
        full: false,         //false按原比例裁切图片,不失真
        fixedBox: true,      //固定截图框大小,不允许改变
        canMove: false,      //上传图片是否可以移动
        canMoveBox: true,    //截图框能否拖动
        original: false,     //上传图片按照原始比例渲染
        centerBox: false,    //截图框是否被限制在图片里面
        height: true,        //是否按照设备的dpr 输出等比例图片
        infoTrue: false,     //true为展示真实输出图片宽高,false展示看到的截图框宽高
        maxImgSize: 3000,    //限制图片最大宽度和高度
        enlarge: 1,          //图片根据截图框输出比例倍数
        mode: '230px 150px'  //图片默认渲染方式
      }
    };
  },
  methods: {
    //初始化函数
    imgLoad (msg) {
    },
    //图片缩放
    changeScale (num = 1) {
      this.$refs.cropper.changeScale(num)
    },
    //向左旋转
    rotateLeft () {
      this.$refs.cropper.rotateLeft()
    },
    //向右旋转
    rotateRight () {
      this.$refs.cropper.rotateRight()
    },
    //实时预览函数
    realTime (data) {
      this.previews = data
    },
    //选择图片
    selectImg (e) {
      let file = e.target.files[0]
      // 校验所选择图片的类型,图片类型要求:jpeg、jpg、png
      if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
        return false
      }
      // 转化为base64
      let reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = (e) => {
        let data = e.target.result
        this.option.img = data
      }
    },
    //上传图片
    uploadImg (type) {
      if (type === 'base64') {
        // 获取截图的 base64 数据
        this.$refs.cropper.getCropData(data => {
          // do something
        })
      } else if (type === 'blob') {
        // 获取截图的blob数据
        this.$refs.cropper.getCropBlob(data => {
          // do something
        })
      }  
    },
  },
}
</script>
<style lang="less" scoped>
.cropper-content{
  display: flex;
  .cropper-box{
    flex: 1;
    .cropper{
      height: 200px;
    }
  }

  .show-preview{
    flex: 1;
    display: flex;
    margin-left: 50px;
    .preview{
      overflow: hidden;
      border:1px solid #67c23a;
      background: #cccccc;
    }
  }
}
.footer-btn{
  margin-top: 10px;
  display: flex;
  .scope-btn{
    display: flex;
    justify-content: space-between;
  }
  .upload-btn{
    flex: 1;
    display: flex;
    justify-content: center;
  }
  .btn {
    font-size: 12px;
    border-radius: 3px;
    color: #fff;
    background-color: #409EFF;
    padding: 8px 15px;
    margin-right: 10px;
  }
}
</style>

qs

        qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库。可以进行对象与字符串之间的一个转换。

        npm 安装插件:

npm install qs

        在 vue 项目中引入插件:

// 方式一:导入项目
import qs from 'qs'

// 方式二:在main.js中设置成全局属性
Vue.prototype.$qs = qs

        qs stringify parse 两个方法。stringify 方法,是将对象序列化成 url  形式的字符串,以 符号进行拼接;parse方法,是将 url  形式的字符串解析成对象。具体使用示例:

// 方法一: qs.stringify(data)
const userObj = {name:'xiaoming',password:'123123'}
qs.stringify(userObj)
console.log('转换后的格式:',qs.stringify(userObj))
// 转换后的格式:name=xiaoming&password=123123

// 方法二: qs.parse(data)
const userStr = 'name=xiaoming&password=123456'
qs.parse(userStr)
console.log('转换后的格式:',qs.parse(userStr))
// 转换后的格式:Object{name:'xiaoming',password:'123456'}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值