vue.js学习

插值
就是通过{{}} 插入实例对象对象中 data 的属性值 ,支持表达式(加减乘除等有结果的),尽搞那么专业的词汇


指令
 

v-text:会替换标签整个内容,{{}}插值方式只替换被扩起的部分,不会解析html内容
v-html:可以渲染html,尽量避免使用,可能会引起xss攻击



v-bind:用来绑定标签上的任何属性,简化语法是:前面的v-bind不用写直接用:
1.动态绑定图片路径
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-text|v-html</title>
</head>
<body>
<div id="app">
    <img v-bind:src="src">
</div>


</body>
<script src="./vue.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            src: './postman.png'
        }
    });

</script>

</html>

2.绑定a标签上的id

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-text|v-html</title>
</head>
<body>
<div id="app">
    <img v-bind:src="src">
    <a v-bind:href="'del.php?id='+id">删除</a>
</div>


</body>
<script src="./vue.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            src: './postman.png',
            id:11,
        }
    });

</script>

</html>

3.绑定class(有两种语法,对象语法,和数组语法)
对象语法:
如果isActive为true,则返回的结果为 <div id="app" class="active"></div>

<div id="app" v-bind:class="{active: isActive}">
    hei
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            isActive: true
        }
    });
</script>

数组语法
渲染结果: <div id="app" class="active text-danger"></div>

<div id="app" v-bind:class="[activeClass, dangerClass]">
    hei
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            activeClass: 'active',
            dangerClass: 'text-danger'
        }
    });
</script>

4.绑定style(有两种语法,对象语法,和数组语法)
对象语法
渲染的结果: <div id="app" style="color: red; font-size: 40px;">hei</div>
 

<div id="app" v-bind:style="{color: redColor, fontSize: font + 'px'}">
    hei
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            redColor: 'red',
            font: 40
        }
    });
</script>

数组语法
渲染结果:<div id="app" style="color: red; font-size: 18px;">abc</div>
 

<div id="app" v-bind:style="[color, fontSize]">abc</div>
  <script>
      var vm = new Vue({
          el: '#app',
          data: {
              color: {
                  color: 'red'
              },
              fontSize: {
                  'font-size': '18px'
              }
          }
      });
  </script>

简化语法:

<div id="app">
    <img v-bind:src="imageSrc">
    <!-- 缩写 --> 
    <img :src="imageSrc">
</div>

v-model:同v-bind一样都是绑定数据,只不过这个是双向绑定,不管 DOM 元素还是 vue 对象,数据的改变都会影响到另一个;
修饰符:

.lazy - 取代 input 监听 change 事件

.number - 输入字符串转为有效的数字

.trim - 输入首尾空格过滤


v-on:绑定事件监听
简写方式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button id="ids" @click="fun">按钮</button>
</body>
<script src="./vue.js"></script>
<script>
    var app = new Vue({
        el:'#ids',
        data:{

        },
        methods:{
            fun:function () {
                console.log(11);
            }
        }
    });
</script>
</html>

用修饰符 阻止浏览器的默认行为
 

<div id="app">
    <a href="http://www.qq.com" @click.prevent="cli">腾百万</a>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        // 将事件处理程序写入methods对象
        methods: {
            cli: function () {
                alert('123');
            }
        }
    });
</script>

使用修饰符绑定一次性事件
 

<div id="app">
    <a href="http://www.qq.com" @click.once="cli($event)">腾百万</a>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        // 将事件处理程序写入methods对象
        methods: {
            cli: function (ev) {
                ev.preventDefault();
                alert('123');
            }
        }
    });
</script>

按键修饰符
绑定键盘抬起事件,但是只有enter 键能触发此事件
 

<div id="app">
    <input type="text"  @keyup.enter="keyup">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {
            keyup:()=>{
                console.log('111')
            }
        }
    });
</script>

系统修饰符
按住 shift 后才能触发点击事件
 

<div id="app">
    <input type="button" value="按钮" @click.shift="cli">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {
            cli:()=>{
                console.log('111')
            }
        }
    });
</script>

鼠标修饰符
鼠标中键触发事件
 

<div id="app">
    <input type="button" value="按钮" @click.middle="cli">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {
            cli:()=>{
                console.log('111')
            }
        }
    });
</script>

为什么在 HTML 中监听事件?
这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。
它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:
1.扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
2.因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
3.当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

 


v-show:显示和隐藏元素(实际上是通过css样式display:none来控制)
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-show</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="app" v-show="is_show">111</div>
<script>
    var app = new Vue({
        el:'#app',
        data:{
            is_show:true//false 为隐藏
        }
    });
</script>
</body>
</html>

v-if / v-else / v-else-if 条件判断

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-if</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="app">
    <div v-if="type == 'A'">A</div>
    <div v-else-if="type == 'B'">B</div>
    <div v-else="type == 'C'">C</div>
</div>
<script>
    var app = new Vue({
        el:'#app',
        data:{
            type:'a'
        }
    });
</script>
</body>
</html>

v-for:比如经常给一个li循环展示数据,支持数组和对象
 

<div id="app">
    <ul>
        <li v-for="(val,key) in arr">{{val}}---{{key}}</li>
    </ul>
    <ul>
        <li v-for="(val,key) in obj">{{val}}---{{key}}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            arr: ['a', 'b', 'c'],
            obj: { id: 1, name: '李四' }
        },
    })
</script>

v-clock:解决vue还没被加载之前会出现花括号的方法,平时基本用不上的
 

<style>
    [v-cloak] {
        display: none;
    }
</style>
<div id="app">
    <p v-cloak>{{obj.id}}</p>
</div>
<script src="./vue.js"></script>
<script>
    setTimeout(() => {
        var vm = new Vue({
            el: '#app',
            data: {
                obj: { id: 1, name: '李四' }
            },
        })
    }, 2000);
</script>

v-once:数据绑定一次
 

<div id="app">
    <p v-once>{{msg}}</p>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg:'kkk'
        },
    })
</script>

匿名函数最大的用处就是,封装作用域
vue之全选与全不选
思路,其实就是遍历元素,然后把所有元素的状态改成和当前选择框的状态一致

<-- html设置v-model="v.stat"   数据来控制是否显示 -->
<input class="toggle" type="checkbox" v-model="v.stat">

//js点击事件		
methods:{
			checkall:function (ev) {
				console.log(1);
				for (let i = 0;i< this.list_data.length;i++){
					//这是全选和反选
					//this.list_data[i].stat = !this.list_data[i].stat;
					//全选和全不选
					this.list_data[i].stat = ev.target.checked;

				}
			}
		}


 


Vue标签template控制数据的显示和隐藏,list_data为你从服务器获取到的数据
<template v-if="list_data.length">
    这里是你要隐藏的html部分    
</template>

添加任务:
 

<input v-on:keyup.enter="addToDo" class="new-todo" placeholder="你想要有什么新的计划?" autofocus>


            addToDo(ev){
			   var title = ev.target.value;
			   var id = 4;
			   var stat = false;
			   this.list_data.push({id,title,stat});

            }

如果被选中就删除
 

<li v-for="(v,k) in list_data" v-bind:class="{completed:v.stat}">


 


删除任务:
给每个li里面的button添加一个事件
 

<button @click="removeToDo(k)" class="destroy"></button>

js代码:
 

splice第一个参数,删除的下标,第二个参数,要删除的个数            
removeToDo(k){
                this.list_data.splice(k,1);
            }

删除全部已经选择的项目
1.先给全部删除增加一个点击事件
 

            removeAll(){
			    //超级精简写法,原理就是谁是false就返回 es6新的语法,只有一个reture的时候可以这么写
			    this.list_data = this.list_data.filter((v)=>!v.stat);
            }

计算属性:缓存数据的作用,减少开销,调用的时候当做一个属性来调用,所以不需要加()号
 

<script>
    var app = new Vue({
        el: '#div',
        data: {
            xing:'',
            ming:'',
        },
        //方法
        methods:{
            
        },
        //计算属性
        computed:{
            fulln(){
                return this.xing+this.ming+Date.now();
            }
        }
    })
</script>

侦听器:侦听数据的改变,侦听的方法名,要和数据的属性名保持一致,形参一:新值,形参二:旧值
比如异步提交数据验证,验证服务器请求错误时还是用旧的值替换

 // 设置侦听器
        watch: {
            // 侦听器中的方法名和要真挺的数据属性名必须一致
            // xing 发生变化,侦听器就会被执行,且将变化后的值和变化前的值传入
            xing:function(newVal,old_val){
                // this.fullname = newVal+this.ming;
                var t = this;
                // 在侦听器中执行异步网络请求
                $.get('./xx.php',(d)=>{
                    t.fullname = d;
                })
            },
        }


 


vue获取节点对象,在某些特殊业务需求的时候来使用ref操作dom,虽然违背mvvm设计原则,但是还是迫不得已要用
 

<p ref='p'>1</p>

this.$refs.p.innerHTML = '2';

 // this.$refs   只是拿到获取节点的工具, 后面跟上标签上ref的值

过滤器:就比如你要过滤掉文本中的敏感词 就可以用这个过滤器
私有过滤器,就是卸载vue实例里面的

var app = new Vue({
    el: '#app',
    data:{msg:'UP'},
    //定义过滤器
    filters:{
        // 过滤器的名称及方法
        myFilters:function(val){
            return val.toLowerCase();
        }
    }
})

全局过滤器,写在外边的

<script>
    Vue.filter('myFilters', function (val) {
        return val.toLowerCase();
    })
    // 定义两个全局过滤器
    Vue.filter('get3', function (val) {
        return val.replace('苍井空','***');
    })


    // 两个Vue 实例
    var app = new Vue({
        el: '#app',
        data: {
            msg: ''
        }
    })
    var app2 = new Vue({
        el: '#app2',
        data: {
            msg: ''
        }
    })
</script>

自定义指令:分为全局自定义指令和私有自定义指令
全局自定义指令获取焦点:

//input 标签上直接使用新的属性 v-getfocus即可

Vue.directive('getfocus',{
        inserted:function (el) {
            el.focus();
        }
    });


局部自定义指令获取焦点
 

<input @keyup.enter="addTodo" v-getfocus class="new-todo" placeholder="请输入" >


// 注册 局部(私有)指令
directives: {
    // 定义指令名称
    getfocus: {
        // 当被绑定的元素插入到 DOM 中时……
        inserted: function (el) {
            // 聚焦元素
            el.focus()
        }
    }
},

自定义指令传值:
 

<p v-color='colors'>这是一段文本</p>

<div id="app">
    <p v-color='colors'>自定义指令的使用</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data:{
            colors:'yellow'
        },
        // 注册 局部(私有)指令
        directives: {
            // 定义指令名称
            color: {
                // 自定义指令可以接受第二个参数
                inserted: function (el,val) {
                    // 第二个参数中包含了指令名称、挂载名称及数据键值
                    console.log(val);
                    // 聚焦元素
                    el.style.color = val.value;
                }
            }
        }
    })
</script>

动画以及过度
在项目中,大多情况下,我们会借助第三方 CSS 动画库来实现,如:Animate.css ;

//给要设置动画的标签用transition 包裹

<transition name="fade">
  <p v-show="is">我是内容</p>
</transition>


//书写样式
<style>
        /* 从有到无 */
        /* 开始 */
        .fade-leave{
            opacity: 1;
        }
        /* 过程 */
        .fade-leave-active
        {
            transition: opacity 1s;
        }
        /* 结束 */
        .fade-leave-to        
        {
            opacity: 0;
        }

        .fade-enter{
            opacity: 0;
        }

        .fade-enter-active{
            transition: opacity 3s;
        }
        .fade-enter-to{
            opacity: 1;
        }
    </style>

json-server  axios
 


todo案例重构(json-server 和 axios):
首先是获取到服务器的数据,npm安装 json-server服务

npm install json-server -g

准备db.json文件
 

{
  "list_data": [
    {
      "id": 1,
      "title": "吃饭",
      "stat": false
    },
    {
      "id": 2,
      "title": "睡觉",
      "stat": true
    },
    {
      "id": 3,
      "title": "打豆豆",
      "stat": false
    }
  ]
}

启动json-server服务
 

json-server --watch db.js
//在页面中直接引入axios.js文件

    var app = new Vue({
        el: '#todoapp',
        data: {
            //默认数据为空
            list_data: {}
        },
        //使用生命周期的钩子函数,请求服务器,获取全部数据
        mounted:function(){
            axios.get("http://localhost:3000/list_data")
                .then((backdata)=>{
                    this.list_data = backdata.data;
                })
        },

添加todu任务
 

//添加todu
            addToDo(ev) {
                var title = ev.target.value.trim();
                if (title == '') {
                    return;
                }
                var id = this.list_data.length + 2;
                var stat = false;
                // 组装数据
                var obj_data = {id, title, stat};

                //发送请求数据入库
                axios.post("http://localhost:3000/list_data",obj_data)
                    .then((backdata)=>{
                        let {data,status} = backdata;
                        if(status == 201){
                            this.list_data.push(data);
                        }
                    });
                //todu添加完成时,清空input文本
                ev.target.value = '';
            },

任务删除

 <button @click="removeToDo(k,v.id)" class="destroy"></button>            

removeToDo(k,id) {
                //发送请求进行删除

                axios.delete("http://localhost:3000/list_data/"+id)
                    .then((backdata)=>{
                        let {data,status} = backdata;
                        if(status == 200){
                            this.list_data.splice(k, 1);
                        }
                    });

            },

任务完成
 

<input @click="complateToDo(k,v.id)" class="toggle" type="checkbox" v-model="v.stat">

       
     complateToDo(k,id){

                var chestat = !this.list_data[k].stat;
                //重新组装新的数据
                newdata = {};
                newdata.id = id;
                newdata.stat = chestat;
                newdata.title = this.list_data[k].title;
                axios.put("http://localhost:3000/list_data/"+id,newdata)
                    .then((backdata)=>{
                        var {data,status} = backdata;
                        if(status != 200){
                            // 具体修改任务列表中那个任务的那个数据值
                            this.list_data[k].stat = chestat;
                        }
                    })

            }

组件的基本使用
组件的好处:组件是可复用的 Vue 实例,且带有一个名字。把这个组件作为自定义元素来使用。组件的好处是写一次可以进行任意次数的复用,简单理解就是当做一个标签用
写法有全局组件,和局部组件
全局组件:

<div id="app">
    <!-- 使用组件 -->
    <!-- 将组件名直接当做标签名在html代码中使用即可 -->
    <mytemp></mytemp>
    <!-- 组件可以进行任意次数的复用 -->
    <mytemp></mytemp>
</div>
<script>
    // 定义一个名为 mytemp 的新组件
    Vue.component('mytemp',{
        // template属性的值,作为组件的内容
        // vue 会把这个值替换到html中并会被浏览器渲染
        template:"<h2>我是一个组件</h2>"
    })
    var app = new Vue({
        el: '#app',
    })
</script>

局部组件

<div id="app">
    <!-- 使用组件 -->
    <!-- 将组件名直接当做标签名在html代码中使用即可 -->
    <mytemp></mytemp>
</div>
<div id="app2">
    <!-- 不可用 -->
    <mytemp></mytemp>
</div>
<script>
    var app = new Vue({
        el: '#app',
        // app 的私有组件,其他实例对象不可用
        components: {
            mytemp: {
                template: "<h2>我是一个组件</h2>",
            }
        }
    })
    var app2 = new Vue({
        el: '#app2',
    })
</script>

组件的使用注意事项
1.组件名如果是驼峰法命名法,大写字母改成小写,然后加一个 -
2.template属性,根标签只有一个
 

<div id="app">
    <!-- 使用组件 -->
    <!-- 将组件名直接当做标签名在html代码中使用即可 -->
    <my-temp></my-temp>
    <!-- 单标签方式使用 -->
    <my-temp/>
</div>
<div id="app2">
    <!-- 不可用 -->
    <mytemp></mytemp>
</div>
<script>
    var app = new Vue({
        el: '#app',
        // app 的私有组件,其他实例对象不可用
        components: {
            // 驼峰法命名
            myTemp: {
                // 必须有唯一的根标签,多标签报错
                template: "<div><h2>我是一个组件</h2><h3>df</h3></div>",
            }
        }
    })
    var app2 = new Vue({
        el: '#app2',
    })
</script>

组件的小例子

<div id="app">
    <tops></tops>
    <lefts></lefts>
    <rights></rights>
</div>
<script>
    var app = new Vue({
        el: '#app',
        components:{
            tops:{
                template:'<div class="top">我是顶</div>'
            },
            lefts:{
                template:'<div class="left">我是左</div>',
            },
            rights:{
                template:'<div class="right">我是右</div>'
            }
        }
    })
</script>


vue组件概念
通过new Vue() 可以得到一个实例对象,其实这个实例对象就是一个特殊的组件,也有 template 参数,也可以当做组件来使用;
vue实例对象也是一个组件,而 mytemp 组件就是运行在 实例对象下面的,这时我们也会将 实例对象称为 父组件,将 mytemp 组件称为 子组件


使用prop向子组件传值

<div id="app">
    <mytemp v-bind:cc="msg" v-bind:kk="msg2"></mytemp>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data:{
            msg:'数据',
            msg2:'数据二'
        },
        components:{
            mytemp:{
                template:'<h2>data:{{cc}}<br>{{kk}}</h2>',
                props:['cc','kk'],
            }
        }
    })
</script>

生命周期:官网有图式,你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
 


路由组件:
 

<!-- 引入路由 -->
<script src="./vue.js"></script>
<script src="./vue-router.js"></script>

<div id="app">
    <ul>
        <li><a href="#/login">登录</a></li>
        <li><a href="#/register">注册</a></li>
    </ul>
    <!-- 路由中设置的组件会替换router-view标签 -->
    <router-view></router-view>
</div>
<script>
    // 1:定义路由组件
    var login = {
        template: '<h2>我是登录页面</h2>'
    }
    var register = {
        template: '<h2>注册有好礼</h2>'
    }

    // 2:获取路由对象
    var ro = new VueRouter({
        // 定义路由规则
        routes: [
            // {请求的路径,componet是模板}
            { path: "/register", component: register },
            { path: "/login", component: login },
        ]
    })

    var app = new Vue({
        el: '#app',
        // ES6 属性简写
        // 3:将router对象传入Vue
        router:ro
    })

</script>

官方为我们提供了 router-link 标签  来替换a标签
 

<li><router-link to="/login">登录</router-link></li>
        <li><router-link to="/register">注册</router-link></li>

使用 router-link 的一大好处就是,每当我们点击时,在标签内就会自动帮我们添加 class 属性,而此时,我们就可以利用 class 属性,来定义样式:
 

<style>
    .router-link-active {
        color: red;
    }
</style>

路由的动态匹配传值
假设有一个用户列表,想要删除某一个用户,需要获取用户的id传入组件内,如何实现呢?
1.通过 <router-link> 传参,在路径上传入具体的值
 

<router-link to="/users/120">用户管理</router-link>

2.路由规则中增加参数,在path最后增加 :id
 

{ path: '/users/:id', component: Users },

3.在组件内部可以使用,this.$route 获取当前路由对象
 

var Users = {
    template: '<div>这是用户管理内容 {{ $route.params.id }}</div>',
    mounted() {
        console.log(this.$route.params.id);
    }
};

命令行工具CLI(好用,掌握)
Vue 提供了一个官方的 CLI,为单页面应用 (SPA) 快速搭建繁杂的脚手架。

初始化项目

安装 cli 命令工具:npm install -g @vue/cli @vue/cli-init

安装成功后,使用 vue -V 命令,查看版本号;

使用 vue init webpack myapp 构建一个名为 myapp 的项目:

Vue 依然使用询问的方式,让我们对项目有一个初始化的信息

Project name:项目名

Project description: 项目描述

Author: 作者

Vue build:

第一种:配合大部分的开发人员  √

第二种:仅仅中有runtime

Install vue-router? 是否安装vue-router  Y

Use ESLint to lint your code? 这个是检测语法错误的插件,询问是否使用这个插件  Y

Pick an ESLint preser:使用哪种语法规范来检查我们的代码:

Standard: 标准规范   √

Airbnb: 爱彼迎规范

Set up unit test: 设置单元测试  N

Setup e2e tests: 设置端对端测试  N

Should we run 'npm install':要不要帮忙你下载这个项目需要的第三方包

使用npm来下载   √

使用yarn来下载

To get started:

  cd myapps
  npm run dev   // 使用命令启动项目
  
  -----
  Your application is running here: http://localhost:8080  
  
  打开浏览器,访问 http://localhost:8080  
  看到浏览器的欢迎界面,表示项目运行成功

到这里一个前端项目就搭建完成了
项目解构介绍

语法检测:
如果我们在 构建项目时 选择了 Use ESLint to lint your code 那么我们在写代码时必须严格遵守 JavaScript Standard Style 代码风格的语法规则

使用两个空格 – 进行缩进

字符串使用单引号 – 需要转义的地方除外

不再有冗余的变量 – 这是导致 大量 bug 的源头!

无分号 – 没什么不好。不骗你!

行首不要以 (, [, or ``` 开头

这是省略分号时唯一会造成问题的地方 – 工具里已加了自动检测!

详情

关键字后加空格 if (condition) { ... }

函数名后加空格 function name (arg) { ... }

坚持使用全等 === 摒弃 == 一但在需要检查 null || undefined 时可以使用 obj == null

一定要处理 Node.js 中错误回调传递进来的 err 参数。

使用浏览器全局变量时加上 window 前缀 – documentnavigator 除外

避免无意中使用到了这些命名看上去很普通的全局变量, open, length, event 还有 name

 


代码项目规范
(1)严格模式: 百度吧,一堆
(2)ES6模块化

CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用;

CommonJS 模块是运行时加载,ES6 模块是编译时输出接口;

ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";

ES6 模块之中,顶层的this指向undefined;CommonJS 模块的顶层this指向当前模块;


 


项目的一整个流程



 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值