从0-1创建Vue项目,整合ElementUI

目录

一、项目创建

1 首先保证安装node.js 与 Vue

2.创建一个文件夹,这里创建了名为VueProject的文件夹,进入该文件的cmd。这里原本是空的,只不过我执行完第3步命令之后生成的东西。

        2.1 在cmd里面执行

 二、项目配置

 三、项目实战

3.1 整合elementUI

 3.2 axios安装

 3.3 路由安装

 3.3.1 路由懒加载

3.3.2 异步组件

 3.4 登陆页面实现

 封装验证规则及token

封装axios

 3.5 后台页面

3.5.1 后台页面布局


 

 

一、项目创建

1 首先保证安装node.js 与 Vue

2.创建一个文件夹,这里创建了名为VueProject的文件夹,进入该文件的cmd。这里原本是空的,只不过我执行完第3步命令之后生成的东西。

5fa8b1c723cd4059a51a56d51f545312.png

 

        2.1 在cmd里面执行

                1. npm init -y                                进行初始化

5b8d2cc0e9664a07b1c6ce09fb8323de.png

 

        2. npm i -D @vue/cli                    创建脚手架

fdaccec7a18a4c90922a36799741f001.png

 

        3. npx vue -V                               查看脚手架版本

8f7c42ea0c984a778e9c66c21f2d3450.png

 

        4. npx vue create project-one      通过脚手架构建

25f3b46325bd4e21b3a9819c003d14db.png

 

这里会让你选择创建vue的哪个版本,我选择的是vue2,选择之后回车,就开始下载了。

955e27bd92f141e6893c04ac4029ab2e.png

 构建完成了一个名为project-one的项目

845c1997f5b049f4862db9f008466262.png

 cd project-one

4337db9bcef74f679f200b97ad960647.png

 执行npm run serve,build中。。。。。

d86c0ec5c7aa4a8c83c4b392a6a57d41.png

 a8708508dcf6493da3c5754088eef6b1.png

打开浏览器,访问localhost:8080 

0eb5453e31874cec8afc1fe330e884b5.png

目录

 


 

d8198a70483a4c2a8f52db365d9109b3.png

 

 二、项目配置

进入project-one文件夹,输入code . 就会用vscode打开该项目了。

263b9114837d45cea8f449a14766142c.png

 df8b8823c88048098a6ae53569404b4c.png

 配置运行npm run serve 自动打开

b1d85c88057e41358e552759bea6cf94.png

 三、项目实战

3.1 整合elementUI

进入project-one文件夹,进入cmd,执行npm i element-ui -S。

a6ecb9425f45429483f5590859aa942d.png

 在package.json里面会多出elementUI的东西。

a1585854830b4664b195ace5466c81ad.png

 依赖导入了,进行引用,进入src->main.js里面。

a079e150ebf54af18285bad91199647a.png

import ElementUI from 'element-ui'            //引入ElementUI
import 'element-ui/lib/theme-chalk/index.css' //导入样式
Vue.use(ElementUI)                            //使用

修改原始HelloWorld.vue 改为Home.vue,修改app.vue

69c88afed2564172a4e9613b2926e52b.png

 964bc570177243588a706d6b85e60942.png

 最终效果

4d56e9d782d446078e89bc3f31ecc71a.png

 3.2 axios安装

进入项目cmd,运行npm i axios -S

9b94d024dd704add9539be3ba7c23f66.png

 进入main.js,配置全局使用

7f09e0b31b63452da878c4e9bb7c2ca6.png

import axios from 'axios'                     //引入axios
Vue.prototype.axios = axios                   // 挂载到原型上,可以全局使用

 3.3 路由安装

进入项目cmd,运行npm i vue-router@3.5.3 -S    因为用的是Vue2版本,所以定义一下router的版本。

81806a419f41460db6a6655ea839ab1c.png

 安装完进行配置,在src目录下新建文件夹router,在该文件夹下创建index.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from '../components/Home.vue'
Vue.use(Router)
export default new Router({
    routes:[
        {
            path:'/',
            component:Home
        }
    ],
    mode:'history'
})

使用,在main.js里面导入并在渲染之前挂载一下

82e008438c394932ad828106ac25aa03.png

在app.vue里面加入路由出口, <router-view></router-view>

f83ddca2b75d4b01808ab84c53f71005.png

 最终显示4df47d9b48944943b0e92cefc9870cdf.png

 3.3.1 路由懒加载

不需要import Home...,只需要在componet后面加import

import Vue from 'vue'
import Router from 'vue-router'
// import Home from '../components/Home.vue'
Vue.use(Router)
export default new Router({
    routes:[
        {
            path:'/home',
            component:()=> import('@/components/Home')
        }
    ],
    mode:'history'
})

3.3.2 异步组件

import Vue from 'vue'
import Router from 'vue-router'
// import Home from '../components/Home.vue'
Vue.use(Router)
export default new Router({
    routes:[
        {
            path:'/home',
            // component:()=> import('@/components/Home') //路由懒加载
            component:resolve => require(['@/components/Home'],resolve) // 异步组件
        }
    ],
    mode:'history'
})

 3.4 登陆页面实现

component文件夹创建Login.vue

<template>
    <div class="login">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>通用后台管理系统</span>
      </div>
      <el-form label-width="80px" :model="form" ref="form">
        <el-form-item label="用户名" prop="username" 
        :rules="[
        {required:true,message:'请输入用户名', trigger:'blur'},
        {min:4,max:10,message:'长度在4-10位字符之间', trigger:'blur'}
        ]">
          <el-input v-model="form.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password"
        :rules="[
        {required:true,message:'请输入密码', trigger:'blur'},
        {min:6,max:12,message:'长度在6-12位字符', trigger:'blur'}
      ]">
          <el-input type="password" v-model="form.password"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="login('form')">登录</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    </div>
  </template>
  
  <script>
  export default {
    name: 'HelloWorld',
    data(){
      return {
        form:{
          username:'',
          password:''
        }
      }
    },
    methods:{
      login(form){
          this.$refs[form].validate((valid)=>{
            if(valid){
              console.log(this.form)
            }else{
              console.error(this.form)
            }
          })
      }
    }
  }
  </script>
  
  <!-- Add "scoped" attribute to limit CSS to this component only -->
  <style scoped>
  .login{
    width: 100%;
    height: 100%;
    position: absolute;
    background: #409EFF;
  }
  .box-card{
    width: 450px;
    margin:200px auto;
  }
  </style>
  

 修改router文件夹下的index.js

import Vue from 'vue'
import Router from 'vue-router'
// import Home from '../components/Home.vue'
Vue.use(Router)
export default new Router({
    routes:[
        {
            path:'/',
            redirect:'/login',
            component:()=> import('@/components/Login') //路由懒加载
        },
        {
            path:'/login',
            name:'/Login',
            component:()=> import('@/components/Login') //路由懒加载
        },
        {
            path:'/home',
            // component:()=> import('@/components/Home') //路由懒加载
            component:resolve => require(['@/components/Home'],resolve) // 异步组件
        }
    ],
    mode:'history'
})

81123ce4e217498c98a54c67a06bb51b.png

 封装验证规则及token

在src下创建utils文件夹,增加validate.js,用来封装验证的方法

57c3a212695143fea24bf3be82fc2854.png

 

// 用户名匹配
export function nameRule(rule,value,callback){
       // 请输入4-10位的昵称
       let reg = /(^[a-zA-Z0-9]{4,10}$)/;
       if(value === ''){
           callback(new Error('请输入用户名'))
       }else if(!reg.test(value)){ // 校验没有通过
           callback(new Error('请输入4-10位用户名'))
       }else{
           callback()
       }
}
// 用户密码匹配
export function passRule(rule,value,callback){
     // 请输入6-12位的密码,需要包含大小写字母和数字以及特殊符号
     let pass = /^\S*(?=\S{6,12})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/;
     if(value === ''){
         callback(new Error('请输入密码'))
     }else if(!pass.test(value)){ // 校验没有通过
         callback(new Error('6-12位密码需要包含大小写字母和数字及符号'))
     }else{
         callback()
     }
}

使用,login.vue全代码

<template>
    <div class="login">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>通用后台管理系统</span>
      </div>
      <el-form label-width="80px" :model="form" ref="form" :rules="rules">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="form.password"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="login('form')">登录</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    </div>
  </template>
  
  <script>
  import {nameRule,passRule } from '../utils/validate.js'
  export default {
    name: 'HelloWorld',
    data(){
      return {
        form:{
          username:'',
          password:''
        },
        rules:{
            username:[{validator:nameRule,trigger: 'blur'}],
            password:[{validator:passRule,trigger: 'blur'}]
        }
      }
    },
    methods:{
      login(form){
          this.$refs[form].validate((valid)=>{
            if(valid){
              console.log(this.form)
            //   this.axios.post('http://localhost:8080/bike/login',this.form)
            //   .then(res =>{
            //     console.log(res)
            //   })
            localStorage.setItem('username',this.form.username)
            this.$message({message:'登陆成功',type:'success'})
            this.$router.push('/home')
            }else{
              console.error(this.form)
            }
          })
      }
    }
  }
  </script>
  
  <!-- Add "scoped" attribute to limit CSS to this component only -->
  <style scoped>
  .login{
    width: 100%;
    height: 100%;
    position: absolute;
    background: #409EFF;
  }
  .box-card{
    width: 450px;
    margin:200px auto;
  }
  </style>
  

在src->utils文件夹下,增加setToken.js,用来封装Token

0e0f2248430a4760958c44be95e15735.png

 

// 设置
export function setToken(tokenKey,token){
    return localStorage.setItem(tokenKey,token)
}
// 获取
export function getToken(tokenKey){
    return localStorage.getItem(tokenKey)
}
// 删除
export function removeToken(tokenKey){
    return localStorage.removeItem(tokenKey)
}

使用,在login.js中使用

4ee3089b7025406ea075f327f677a136.png

 

封装axios

1.在src目录下新建service.js

import axios from 'axios'
import {getToken} from '@/utils/setToken.js'
import { Message } from 'element-ui'
const service = axios.create({
    baseURL:'/api', //baseURL会自动加在请求地址上
    timeout:5000
})
// 添加请求拦截器
service.interceptors.request.use((config)=>{
    // 在请求之前做些什么(获取并设置token)
    config.headers['token'] = getToken('token')
    return config
},(error)=>{
    return Promise.reject(error)
})

// 添加响应拦截器
service.interceptors.response.use((response)=>{
    // 在响应数据做些什么(获取并设置token)
    let {code, msg} = response.data
    if(code !== 200){
        Message({message: msg || 'error',type:'warning'})
    }
     return response
},(error)=>{
    return Promise.reject(error)
})
export default service

2.去vue.config.js配置代理

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    open:true,  // 自动打开
    host: 'localhost',
    proxy:{ // 配置代理
      '/api':{
        target:'http://localhost:8080/bike',
        changeOrigin:true, //允许跨域
        pathRewrite:{
          '^/api':''
        }
      }
    }
  }
})


3.去main.js,替换原来的axios为自己的service

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

import ElementUI from 'element-ui'            //引入ElementUI
import 'element-ui/lib/theme-chalk/index.css' //导入样式
// import axios from 'axios'                     //引入axios
import router from './router'                 //引入router
import service from './service'

Vue.prototype.service = service                   // 挂载到原型上,可以全局使用
Vue.use(ElementUI)                            //使用

Vue.config.productionTip = false

new Vue({
  router,                                     // 渲染之前挂载一下
  render: h => h(App),
}).$mount('#app')

4.使用,这里是后端自己定义的接口

 @PostMapping("login")
    public Map<String,Object> login(@RequestBody LoginParam param){
        Map<String,Object> res = new HashMap<>();
        if (param.getUsername()!= null && param.getPassword() != null){
            res.put("code",200);
            res.put("msg","登录成功");
            res.put("username",param.getUsername());
            res.put("token","123456");
            return res;
        }
        else {
            res.put("code",201);
            res.put("msg","登录失败");
            return res;
        }
    }

LoginParam.java

package com.zsp.bike.entity.param;

import lombok.Data;

import java.io.Serializable;

@Data
public class LoginParam implements Serializable {
    private String username;
    private String password;
}

在login.vue写请求方法,并存储token

login(form){
          this.$refs[form].validate((valid)=>{
            if(valid){
                console.log(this.form)
                let LoginParam = this.form
                this.service.post('/login',LoginParam)
                .then(res=>{
                  console.log(res)
                  if(res.data.code === 200){
                    setToken('username',res.data.username)
                    setToken('token',res.data.token)
                    this.$message({message:res.data.msg, type:'success'})
                    this.$router.push('/home')
                  }        
                })     
            }else{
              console.error(this.form)
            }
          })
      }

api请求封装,在src目录下新建api文件夹,创建api.js

d2ba8fd18b3d4c88b6f53ded3bfdaaea.png

// 项目中我们大多数时候都会把对应的接口请求都封装成api来调用
import service from '../service.js'

// 登录接口封装
export function login(data){
    return service({
        method: 'post',
        url:'/login',
        data
    })
}

 使用,在login.vue中首先导入这个api中定义的login,然后使用

  import { login } from '@/api/api.js'
  export default {
    name: 'HelloWorld',
    data(){
      return {
        form:{
          username:'',
          password:''
        },
        rules:{
            username:[{validator:nameRule,trigger: 'blur'}],
            password:[{validator:passRule,trigger: 'blur'}]
        }
      }
    },
    methods:{
      login(form){
          this.$refs[form].validate((valid)=>{
            if(valid){
                console.log(this.form)
                let LoginParam = this.form  
                login(LoginParam).then(res=>{
                    if(res.data.code === 200){
                      setToken('username',res.data.username)
                      setToken('token',res.data.token)
                      this.$message({message:res.data.msg, type:'success'})
                      this.$router.push('/home')
                  }  
                })   
            }else{
              console.error(this.form)
            }
          })
      }

登录成功

2ade3ac06cce4381a82d53a5b2dbcc79.png

 

创建404页面,在src->components文件夹下新建NotFound.vue

<template>
    <div class="notfound">
        <div class="wrapper">
            <div class="big">页面不见了</div>
            <div>去首页瞧瞧,点击<router-link to="/">这里</router-link>进入首页</div>
        </div>
    </div>
</template>
<script>
export default {
    data(){
        return {};
    }
}
</script>
<style>
.notfpund{
    height: 100%;
    background-image: url('../assets/404.jpg');
    background-position: right top, center center;
    background-repeat:  no-repeat repeat;
}
.notfound .wrapper .big{
    font-size: 74px;
    font-weight: 700;
    line-height: 68px;
    margin-bottom: 48px;
}
</style>

需要在app.vue中设置body和html宽高,否则不生效

d043c04ed1564c04bee09f1e63ad8ee6.png

1729165c7035404da99f23f74a6c4dc4.png

 3.5 后台页面

3.5.1 后台页面布局

在src->components文件夹下创建common文件夹。

813fff729a45473f88dd2f862ee8e9a4.png

头部、底部、菜单最终实在Home.vue中写的

afb246c76d0d4e04bb7a946251b266c0.png

在Home.vue中导入三个组件

<template>
  <div class="home">
    <!-- 头部 -->
    <Header>Header</Header> 
    <el-container class="content">
      <!-- 左侧菜单栏 -->
        <Menu/>
        <!-- 内容 -->
      <el-container>
        <el-main>Main</el-main>
        <!-- 底部 -->
        <el-footer><Footer/></el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import Header from './common/Header.vue'
import Footer from './common/Footer.vue'
import Menu from './common/Menu.vue'
export default {
  name: 'HelloWorld',
  components:{ //注册
    Header,
    Footer,
    Menu
  },
  data(){
    return {}
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .home{
    width:100%;
    height:100%;
  }
  .content{
    position: absolute;
    width: 100%;
    top:60px;
    bottom: 0;
  }
</style>

 5374dd4379c947cd96267204352952b2.png

header的书写,左侧展示标题,右侧展示用户名

<template>
    <div class="header">
        <el-header>
            <div class="title">管理系统</div>
            <div>{{name}}</div>
        </el-header>
    </div>
</template>
<script>
import { getToken } from '@/utils/setToken';
export default{
    name:"Header_",
    data(){
        return{
            name:''
        }
    },
    created(){
       this.name = getToken('username')
    }
}
</script>
<style scoped>
.el-header{
    background: #2578b5;
    color:#fff;
    line-height: 60px;
    display: flex;
    justify-content: space-between;
}
.title{
    width: 200px;
    font-size: 24px;
}
</style>

footer的书写

<template>
    <div class="footer">
       <el-card>
        China 2023 Casey
       </el-card>
    </div>
</template>
<script>
export default{
    name:"footer_",
    data(){
        return{}
    }
}
</script>

Menu.vue的书写

<template>
    <div class="menu">
        <el-aside width="200px">
            <el-menu
            default-active="2"
            class="el-menu-vertical-demo"
            background-color="#2578b5"
            text-color="#fff"
            active-text-color="#ffd04b">
            <el-submenu index="1">
              <template slot="title">
                <i class="el-icon-location"></i>
                <span>导航一</span>
              </template>
              <el-menu-item-group>
                <el-menu-item index="1-1">选项1</el-menu-item>
                <el-menu-item index="1-2">选项2</el-menu-item>
              </el-menu-item-group>
              </el-submenu>
          </el-menu>
        </el-aside>
    </div>
</template>
<script>
export default{
    name:"menu_",
    data(){
        return{}
    }
}
</script>
<style scoped>
.el-aside{
    height: 100%;
}
.el-menu{
    height: 100%;
}
.el-submenu-item{
    min-width: 0;
}
</style>

最终效果

13cd6b45abbb48c498f59042c77b174f.png

 

3.5.2 路由的渲染,将路由渲染到菜单Menu中

在components文件夹下创建bike和bikeupdate文件夹。

c1b0846b93794bf5a1a9a4ffa736cf42.png

修改路由,进入router.js

import Vue from 'vue'
import Router from 'vue-router'
// import Home from '../components/Home.vue'
Vue.use(Router)
export default new Router({
    routes:[
        {
            path:'/',
            redirect:'/login',
            hidden:true,
            component:()=> import('@/components/Login') //路由懒加载
        },
        {
            path:'/login',
            name:'/Login',
            hidden:true,
            component:()=> import('@/components/Login') //路由懒加载
        },
        {
            path:'*',
            name:'NotFound',
            hidden:true,
            component:()=> import('@/components/NotFound') //路由懒加载
        },
        // {
        //     path:'/home',
        //     // component:()=> import('@/components/Home') //路由懒加载
        //     component:resolve => require(['@/components/Home'],resolve) // 异步组件
        // },

        // 第一个
        {
            path:'/home',
            name:'车辆管理',
            redirect:'/home/bike',  //默认重定向
            component:()=> import('@/components/Home'),
            children:[
                {
                    path:'/home/bike',  
                    name:'车辆列表',
                    component:()=> import('@/components/bike/BikeList'),//这里对应文件的名字,我创建的是BikeList
                },
                {
                    path:'/home/ment',  
                    name:'车辆管理',
                    component:()=> import('@/components/bike/BikeMent'),//这里对应文件的名字,我创建的是BikeList
                },
                {
                    path:'/home/info',  
                    name:'信息列表',
                    component:()=> import('@/components/bike/InfoList'),//这里对应文件的名字,我创建的是BikeList
                }
            ]
        },

        // 第二个
        {
            path:'/home',
            name:'数据渲染',
            component:()=> import('@/components/Home'),
            children:[
                {
                    path:'/home/dataview',  
                    name:'数据概览',
                    component:()=> import('@/components/bikeUpdate/DataView'),//这里对应文件的名字,我创建的是BikeList
                }
            ]
        }
    ],
    mode:'history'
})

 完成上部分后,去Menu.vue 菜单页完成渲染

<template>
    <div class="menu">
        <el-aside width="200px">
            <el-menu
            router
            default-active="2"
            class="el-menu-vertical-demo"
            background-color="#2578b5"
            text-color="#fff"
            active-text-color="#ffd04b">

            <!-- 在这里遍历,进行绑定 -->
            <template v-for="(item,index) in menus">
                <el-submenu :index="index+''" :key="index" v-if="!item.hidden">
                    <template slot="title">
                      <i class="el-icon-location"></i>
                      <span>{{item.name}}</span>
                    </template>
                    <el-menu-item-group v-for="(child,index) in item.children" :key="index">
                      <el-menu-item :index="child.path">{{child.name}}</el-menu-item>
                    </el-menu-item-group>
                    </el-submenu>
            </template>
          </el-menu>
        </el-aside>
    </div>
</template>
<script>
export default{
    name:"menu_",
    data(){
        return{
            menus:[]
        }
    },
    created(){
        console.log(this.$router.options.routes)
        this.menus = [...this.$router.options.routes]
    }
}
</script>
<style scoped>
.el-aside{
    height: 100%;
}
.el-menu{
    height: 100%;
}
.el-submenu-item{
    min-width: 0;
}
</style>

 92c5aa901b76417e870c9e462bd036e1.png

 设置路由出口,让Main区域跟着路由变化而显示不同的内容。在Home.vue中修改,把原始的Main改为router-view

1350333870ae4e81b29101fbb2aa841f.png

 3b252365f3f04f3c8eba3f4649faaaeb.png

接下来创建面包屑 ,在component文件夹下创建Breadcrumb.vue

<template>
    <div>
        <el-card>
            <el-breadcrumb separator-class="el-icon-arrow-right">
                <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
                <el-breadcrumb-item
                v-for="(item,index) in $route.matched"
                :key="index"
                >{{item.name}}</el-breadcrumb-item>
              </el-breadcrumb>
        </el-card>
    </div>
</template>
<script>
export default{
    name:"Breadcrumb_",
    data(){
        return{}
    }
}
</script>
<style scoped>
</style>

在Home.vue中注册

<template>
  <div class="home">
    <!-- 头部 -->
    <Header>Header</Header> 
    <el-container class="content">
      <!-- 左侧菜单栏 -->
        <Menu />
        <!-- 内容 -->
      <el-container>
        <el-main>
          <!-- 面包屑 -->
          <Bread />
          <div class="cont">
            <router-view></router-view>
          </div>     
        </el-main>
        <!-- 底部 -->
        <el-footer><Footer /></el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import Bread from './common/Breadcrumb'
import Header from './common/Header'
import Footer from './common/Footer'
import Menu from './common/Menu.vue'
export default {
  name: 'HelloWorld',
  components:{ //注册
    Header,
    Footer,
    Menu,
    Bread
  },
  data(){
    return {}
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .home{
    width:100%;
    height:100%;
  }
  .content{
    position: absolute;
    width: 100%;
    top:68px;
    bottom: 0;
  }
  .count{
    margin:20px 0;
  }
</style>

 

7b3b7c7e0e0d4fc0a45b9e2eebf20c69.png

 以上就是全部内容。

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值