vue学习笔记

一、vue的基础使用

1.双大括号插值法  {{xxx}}

2.有tempalte的情况下,加载template的内容

3.引用vue,npm install vue的包后,通过script标签引入

4.常用样式:

let vm=new Vue({

        el:".demo",

        data:function(){

            return{
                //数据属性
                msg:"这是一段测试的数据"

            }

        },

        template:`

            <div class="tem"></div>

        `,

        methods:{

            //里面放v-on绑定的时间函数

            cilckHander(e){

                console.log(e);

            }

        }

    })

5.Vue的具体使用和API文档:Vue的中文官网

二、Vue的指令系统

1.v-text   相当于innerText

<a v-text="msg" href="http://" target="_blank" rel="noopener noreferrer""></a>

2.v-html   相当于innerHTML

<div v-html="msg2"></div>

3.v-show   相当于dispaly属性

<i v-show="radom>0.5">随机显示{{radom}}</i>

4.v-if  v-else    数据属性值对应的值如果为假,则不在页面中渲染  相当于appendChild()、removeChild()

<p v-if="isTrue">渲染true</p>
<p v-else>渲染false</p>

5.v-bind   绑定标签上的属性(内置属性或自定义属性)  简写可省略v-bind  

//绑定内置属性
<div class="box" v-bind:class="{active:isTrue}"></div>
<img src="" alt="图片加载失败" :src="imgSrc"></img>
//绑定自定义属性
<div v-bind:aaa="text"></div>
//没有冒号后的判断时,变量不需要{}括起来

6.v-on  给标签绑定事件   简写用@

<div class="box" v-on:click='clickHander'></div>
<div class="box" @click='clickHander'></div>

7.v-for  循环遍历,可以是对象,数组等

<ul>
    //遍历对象数组
    <li v-for="(item,index) in lists">
        id: {{item.id}}<br>
        name: {{item.name}}<br>
        age: {{item.age}}<br>
        index: {{index}}
    </li>
    //遍历一个对象内的key-value
    <li v-for="(value,key) in person">
        {{key}}: {{value}}
    </li>
</ul>

详细指令使用:Vue指令系统

三、组件

1.局部组件

a.局部组件声明,组件内的data一定是个函数

let APP = {
        data: function () {
            return {
                msg: "这是一段data数据"
            }
        },
        template: `
        <ul>
            <li> {{msg}} </li>
            <li> {{msg}} </li>
            <li> {{msg}} </li>
        </ul>
        `
    };

b.局部组件挂载,挂载在Vue的components上

components: {
            APP
        },

c.局部组件使用,只能在template中引用

template: `
            <div class="tem">
                <APP/>
            </div>
        `

2.全局组件

使用Vue.component(name,options),第一个参数是组件名,第二个是组件具体内容,与局部组件一样

let my = Vue.component("Mybtn", {
        data: function () {
            return {
                
            }
        },
        template: `
            <button>按钮</button>
        `
    });

全局组件的使用同局部组件一样

3.通过prop挂子通信

父组件向子组件传递数据

a.想给父组件中绑定自定义的属性

b.在子组件中使用props接收父组件传递的数据

c.可以在子组件中任意使用

        /*------子组件------*/
        Vue.component('Child',{
            template:`
                <div>
                    <p>这是一个子组件</p>
                    <input type="text" v-model="childData"/>
                    <p>childData:{{childData}}</p>
                </div>
            `,
            // 通过props接收数据
            props:['childData']
        });
        /*------父组件------*/
        Vue.component('Parent',{
            data(){
                return{
                    msg:'这是来自父组件的数据'
                }
            },
            // 将要传递的数据绑定在子组件属性上
            template:`
                <div class="tem">
                    <p>这是一个父组件</p>
                    <Child :childData="msg"/>
                    <p>msg:{{msg}}</p>
                </div>
            `
        });

注:对于多层组件之间的数据传递,可以使用v-bind='$attrs',传递数据的值($attrs的值就是props的值) 

4.通过事件向子组件发送消息

子组件向父组件传递数据

a.在父组件绑定自定义的事件childHander

b.在子组件中 触发原生事件 在函数中使用$emit触发父组件当中自定义的事件childHander

c.this.$emit('要触发的事件名',传递数据);//this.$emit('childHander',val);

//这里有子组件与父组件的数据双向传递
    /*-------子组件------*/
    Vue.component('Child', {
        data:function(){
            return{
                msg:'这是子组件的数据'
            }
        },
        template: `
            <div>
                <p>这是子组件</p>
                <input type='text' v-model="childData"  @input="valueChange(childData)">
            </div>
        `,
        methods:{
            valueChange(val){
                this.$emit('childHander',val);
            }
        },
        props:['childData']
    });
    /*-------父组件------*/
    Vue.component('Parent', {
        data: function () {
            return {
                msg: '这是一条来自父组件的数据'
            }
        },
        template: `
            <div>
                <p>这是父组件</p>
                <Child :childData="msg" @childHander='childHander'/>
                <p>msg:{{msg}}</p>
            </div>
        `,
        methods:{
            childHander(val){
                this.msg=val;
            }
        }
    });
    let vm = new Vue({
        el:'.demo',
        data(){
            return{

            }
        },
        template:`
            <div>
                <Parent/>
            </div>
        `
    })

注:1.对于多层组件数据传递,在中间层组件数据传递可用v-on='$listener' 代替中间层的事件绑定。

2.在中央事件总线创建公共的类中,可以配套使用$emit():触发自定义的事件和$on():绑定自定义事件,绑定到同一个实例化对象中(可以定义一个中央示例化对象),用于兄弟间组件传值

3.关于传值总结:

 

三、具名插槽

slot的使用:<slot name='one'></slot>与<标签 slot='one'>第一个插槽</标签>对应

let APP = {
        template: `
            <ul>
                <slot name='one'></slot>
                <slot name='two'></slot>
            </ul>
        `
    };
    let vm = new Vue({
        components: {
            APP
        },
        template: `
            <div class="tem">
                <APP>
                    <li slot='one'>第一个插槽</li>
                    <li slot='two'>第二个插槽</li>
                <APP/>
            </div>
        `
    })

四、过滤器

过滤器的作用:为页面中数据进行添油加醋的工作

1.步骤

a).声明过滤器  局部过滤器/全局过滤器

b).使用过滤器  {{数据|过滤器名字}}或v-bind里面  ' | '为通道符

2.局部过滤器 filters:{}

let Filter1={
        data:function(){
            return{
                msg:'这是一条来自Filter的数据',
                message:''
            }
        },
        template:`
            <div>
                <input type='text' v-model='message'></input>
                <h3>{{message|filterMessage}}</h3>
                <h4>{{msg|changeMsg('这是全局过滤器')}}</h4>
            </div>
            
        `,
        filters:{
            filterMessage:function(val){
                if(val.trim()){
                    return '¥'+val;
                }
            }
        }
    }

3.全局过滤器  Vue.filter(过滤器名字,函数);

Vue.filter('changeMsg',function(val,arg){
        return arg+' '+val.split('').reverse().join('');
    })

注:所有过滤器中的函数中,第一个参数都是通道符号  ‘|’  前的数据(要过来操作的数据),后面的参数为函数传入的参数值

 五、监听数据

watch监听的是单个属性

1.简单监视  基本的数据类型

<body>
    <div class="demo">
        <input type="text" v-model='msg'>
        <h3>{{msg}}</h3>
    </div>
</body>
    <script type="text/javascript">
        let vm=new Vue({
            el:'.demo',
            data:function(){
                return{
                    msg:'这是一段数据'
                }
            },
            watch:{
                   msg:function(newV,oldV){
                       console.log(newV,oldV);
                   }
            }
        })
    </script>

2.复杂监视  复杂的数据类型

<body>
    <div class="demo">
        <button @click="arrayM[0].name='Roy'">变化</button>
        <h3>{{arrayM[0].name}}</h3>
    </div>
</body>
    <script type="text/javascript">
        let vm=new Vue({
            el:'.demo',
            data:function(){
                return{
                    arrayM:[{name:'jack'},{name:'lan'}]
                }
            },
            watch:{
                arrayM:{
                    deep:true,//深度监听
                    handler:function(nV,oV){
                        console.log(nV[0].name);
                    }
                }
            }
        })
    </script>

六、计算属性  (监听的数据不在data里面)

1.定义监听数据方法  computed    

computed: {
            musicSrc: function () {
                return this.musicData[this.currentIndex].musicsrc;
            }
        }

2.使用监听数据

 <audio :src="musicSrc" autoplay controls loop=-1></audio>
 <p style="margin: 10px;">正在播放:{{musicSrc}}</p>

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./node_modules/vue/dist/vue.min.js" type="text/javascript"></script>
    <style>
        *{
            padding: 0;
            margin: 0;
        }

        ul>li{
            background-color: rgba(0, 255, 255, 0.61);
            margin: 10px 10px;
            border-radius: 5px;
            padding: 10px;
            list-style: none;
        }

        .active{
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div class="demo">
        <audio :src="musicSrc" autoplay controls loop=-1></audio>
        <br>
        <p style="margin: 10px;">正在播放:{{musicSrc}}</p>
        <ul>
            <li v-for='(item,index) in musicData' @click='changeMusic(index)' :class='{active:currentIndex==index}'>
                歌曲名:{{item.name}}<br>
                地址:{{item.musicsrc}}
            </li>
        </ul>
    </div>
</body>
<script type="text/javascript">
    let vm = new Vue({
        el: '.demo',
        data: function () {
            return {
                musicData: [
                    { id: 1, name: '戒烟', musicsrc: './audio/戒烟.mp3' },
                    { id: 2, name: '时间飞行', musicsrc: './audio/时间飞行.m4a' },
                    { id: 3, name: '牛奶面包', musicsrc: './audio/牛奶面包.mp3' },
                    { id: 4, name: '离骚', musicsrc: './audio/离骚.mp3' }
                ],
                currentIndex:0
            }
        },
        computed: {
            musicSrc: function () {
                return this.musicData[this.currentIndex].musicsrc;
            }
        },
        methods:{
            changeMusic(num){
                this.currentIndex=num;
                this.isPlay=num;
                // let current=document.querySelector("ul").childNodes;
                // for(var i=0;i<current.length;i++){
                //     current[i].setAttribute('class','');
                // }
                // current[num].setAttribute('class','active');
            }
        }
    })
</script>

</html>

七、生命周期

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./node_modules/vue/dist/vue.min.js" type="text/javascript"></script>
</head>
<body>
    <div id="demo">
        <!-- Vue内置组件<keep-alive></keep-alive>能在组件切换过程中间状态保留在内存中。防止重复渲染 -->
        <keep-alive>
            <app-template v-if='isAdd'></app-template>
        </keep-alive>
        <br>
        <button @click='isAdd=!isAdd'>改变生死</button>
    </div>
</body>
<script type="text/javascript">
    //局部组件
    let appTemplate={
           data:function(){
               return{
                   msg:'这是来自局部组件APP的数据'
               }
           },
           template:`
               <div class='app'>
                    <div>{{msg}}</div><br>
                   <button @click='changeHandler'>改变内容</button>
               </div>
           `,
           methods:{
                changeHandler(){
                    this.msg='TFBOYS';
                }
           },
           beforeCreate:function(){
                //组件创建之前
                console.log(this.msg);//undefined
           },
           created:function(){
                //组件创建之后  在created这个方法中可以操作后端数据,数据驱动视图
                //应用:发起ajax请求
                console.log(this.msg);//'这是来自局部组件APP的数据'
           },
           beforeMount:function(){
                //数据挂载到DOM之前
                console.log(document.querySelector('#demo'));
           },
           mounted:function(){
               //数据挂载到DOM之后  会调用Vue作用以后的DOM
               console.log(document.querySelector('#demo'));
           },
           beforeUpdate:function(){
               //在更新DOM之前 调用该钩子  应用:可以获取原始的DOM元素
               console.log(document.querySelector('#demo').innerHTML);
           },
           updated:function(){
               //在更新DOM之后 调用该钩子  应用:可以获取最新的DOM元素
               console.log(document.querySelector('#demo').innerHTML);
           },
           beforeDestroy:function(){
               //组件销毁之前
               console.log('beforeDestroy:');
           },
           destroyed:function(){
                //组件销毁之后
               console.log('destroyed:');
           },
           activated:function(){
               console.log('组件被激活了');
           },
           deactivated:function(){
               console.log('组件停用了');
           }
       }
       let vm=new Vue({
           el:'#demo',
           data:function(){
               return{
                   msg:'这是来自Vue的数据',
                   isAdd:true
               }
           },
           components:{
                appTemplate
           }
       });
   </script>
</html>

注意:

1.组件命名:小写html页面加载没有问题,大写如:appTemplate,引用时要变成<app-template/>

2.上述代码如果组件引用换成在Vue的template里面,结果会巨大变化(DOM元素挂载与template加载时间上不一样)

3.  Vue内置组件<keep-alive></keep-alive>能在组件切换过程中间状态保留在内存中。防止重复渲染。使用了<keep-alive></keep-alive>,beforeDestroy和destroyed方法将失效,改为采用activated和deactivated方法

八、 获取DOM元素

1.给DOM元素添加ref属性;如:ref='mydom'

2.通过实例对象的$refs内置属性获取DOM元素;如:this.$refs.mydom

3.上述步骤只能获取更新前的DOM元素,如果页面发生了变化,则要是用$nextTick(
)方法来获取更新后的DOM元素

let myTemplate={
            data:function(){
                return{
                    msg:'这是来自myTemplate的数据',
                    isShow:false
                }
            },
            template:`
                    <div class='mytem'>
                        <p ref='myp'>{{msg}}</p> 
                        <input type='text' v-show='isShow' ref='input'/>   
                    </div>
            `,
            mounted:function(){
                this.isShow=true;//更新了页面
                this.$nextTick(function(){
                    this.$refs.input.focus();
                }),
            //$nextTick与放在updated里的效果相同
            // updated:function(){
            //     this.$refs.input.focus();
            // }
            }
        }

九、路由

1.引包

2.创建VueRouter对象

3.配置路由规则

4.将路由挂载到实例对象Vue上

let router=new VueRouter({
        routes:[
            {
                path:'/login',
                name:'login',
                component:login
            },
            {
                path:'/register',
                name:'register',
                component:register
            }
        ]
    });

5.使用路由   router-link==>a  to==>href

template:`
            <div>
                <router-link to='/login'>登入</router-link>
                <router-link to='/register'>注册</router-link>
                <router-view>hhh</router-view>
            </div>
        `

6.路由的参数

a).   path:'/login/:id'     :to="{name:'login',params:{id:1}}"

b).   path:'/register      :to="{name:'register',query:{userId:1}}"

let router=new VueRouter({
        routes:[
            {
                path:'/login/:id',
                name:'login',
                component:login
            },
            {
                path:'/register',
                name:'register',
                component:register
            }
        ]
    });
    let vm=new Vue({
        router,
        template:`
            <div>
                <router-link :to="{name:'login',params:{id:1}}">登入</router-link>
                <router-link :to="{name:'register',query:{userId:1}}">注册</router-link>
                <router-view>hhh</router-view>
            </div>
        `
    })

7.参数获取

在相应的组件(配置到路由里面的组件)的created生命周期里查找this.$route.params.xxx或this.$route.query.xxx xxx

8.嵌套路由 children:[{路由配置},{路由配置}]

let router=new VueRouter({
        routes:[
            {
                path:'/login/:id',
                name:'login',
                component:login,
                children:[
                    {
                        path:'/login/music',
                        name:'music',
                        component:music
                    },
                    {
                        path:'/login/movie',
                        name:'movie',
                        component:movie
                    }
                ]
            },
            {
                path:'/register',
                name:'register',
                component:register
            }
        ]
    });

总结

9.动态路由

实现切换到相同组件,但是数据不一样,用watch监听$route的变化来获取相同组件切换携带的参数值

        //公共组件
        let conDec={
            data:function(){
                return{
                    msg:''
                }
            },
            template:`
                <div>
                    我是{{msg}}
                </div>
            `,
            created:function(){
                this.msg=this.$route.params.id;//获取不同组件切换携带的参数
            },
            watch:{
                '$route'(to,from){
                    this.msg=to.params.id;//获取相同/公共组件之间切换携带的参数
                }
            }
        }
        let Home={
            template:`
                <div>
                    这是主页
                    <div>
                        <router-link :to="{name:'condec',params:{id:1}}">前端</router-link>
                        <router-link :to="{name:'condec',params:{id:2}}">后端</router-link>
                        <router-view></router-view>
                    </div>
                </div>
            `
        }
        let router=new VueRouter({
            routes:[
                {
                    path:'/home',
                    name:'home',
                    component:Home,
                    children:[
                        {
                            path:'/home/:id',
                            name:'condec',
                            component:conDec
                        }
                    ]
                },
                {
                    path:'/login',
                    name:'login',
                    component:Login
                }
            ]
        });

注:如果要在组件切换时保存组件状态,可以采用<keep-alive></keep-alive> 保存组件状态

10.路由meta的使用和权限限制

a).跳转需要权限(如登入方可查看)的路由配置中添加meta:{auth:true}

b).通过router.beforeEach((to,from,next)=>{判断to.meta.auth和localStorage是否为空,来控制路由跳转权限})

c).localStorage.setItem('user',{name:this.name,password:this.password})   给本地存储添加数据

localStorage.getItem('user');    获取本地存储数据   localStorage.clear();   清空本地存储的数据

代码实现如下:

<body>
    <div class="demo">
        <router-link :to="{name:'home'}">首页</router-link>
        <router-link :to="{name:'blog'}">博客</router-link>
        <router-link :to="{name:'login'}">登入</router-link>
        <a href="javascript:void(0)" @click='handleOut'>退出</a>
        <router-view></router-view>
    </div>
</body>
    <script>
        let Home={
            template:`
                <div>我是主页界面</div>
            `
        }
        let Blog={
            template:`
                <div>我是博客界面</div>
            `
        }
        let Login={
            template:`
                <div>
                    我是登入界面
                    <div>
                            账号:<input type='text' name='name'/><br>
                            密码:<input type='password' name='password'/><br>
                            <button @click='handleLogin'>提交</button>
                    </div>
                </div>
            `,
            methods:{
                handleLogin(e){
                    localStorage.setItem('user',{name:this.name,password:this.password})
                    // this.$router.options.routes[2].meta.auth=false;
                    this.$router.push('blog');
                }
            },
            mounted:function(){
                if(localStorage.getItem('user')){
                    alert('你已经成功登入!');
                    this.$router.push('home');
                }
            }
        }
        let router=new VueRouter({
            routes:[
                {
                    path:'/',
                    redirect:'/home'
                },
                {
                    path:'/home',
                    name:'home',
                    component:Home
                },
                {
                    path:'/blog',
                    name:'blog',
                    component:Blog,
                    meta:{
                        auth:true
                    }
                },
                {
                    path:'/login',
                    name:'login',
                    component:Login
                }
            ]
        });
        router.beforeEach((to,from,next)=>{//权限控制
            if(to.meta.auth){
                if(localStorage.getItem('user')){
                    next();
                }
                else{
                    next('/login');
                }
            }
            else{//如果访问的不是blog页面auth都是false
                next();//避免加载卡顿
            }
        });
        let vm=new Vue({
            el:'.demo',
            data:function(){
                return{
                    msg:'this is message'
                }
            },
            router,
            methods:{
                handleOut(){
                    localStorage.clear();//退出登入
                }
            }
        });
    </script>

11.导航守卫

详细使用参考:导航守卫

使用组内守卫实现离开保存的功能

let music_movie = {
        data() {
            return {
                msg: 'music',
                answer:{'music':false,'movie':false}
            }
        },
        template: `
            <div>
                This is {{msg}}<br/>
                <button >保存</nutton>
            </div>
        `,
        watch: {
            '$route'(to, from) {
                this.msg=to.params.idname;
            }
        }
        beforeRouteLeave(to, from, next) {
            let currPage=to.params.id
            const isSave=this.answer.currPage= window.confirm('Do you really want to leave? you have unsaved changes!');
            if (isSave) {
                next()
            } else {
                next(false)
            }
            
        }
    }
    let login = {
        data: function () {
            return {
                msg: '这是登入界面'
            }
        },
        template: `
            <div>
                {{msg}}
                <br>
                <router-link :to="{name:'music',params:{idname:'music'}}">音乐</router-link>
                <router-link :to="{name:'movie',params:{idname:'movie'}}">电影</router-link>
                <router-view></router-view>
            </div>
        `
    }
    let router = new VueRouter({
        routes: [
            {
                path: '/login/:id',
                name: 'login',
                component: login,
                children: [
                    {
                        path: '/login/:idname',
                        name: 'music',
                        component: music_movie
                    },
                    {
                        path: '/login/:idname',
                        name: 'movie',
                        component: music_movie
                    }
                ]
            }
        ]
    });

    let vm = new Vue({
        el: '.demo',
        router,
        template: `
            <div>
                {{msg}}
                <br>
                <router-link :to="{name:'login',params:{id:1}}">登入</router-link>
                <router-view></router-view>
            </div>
        `
    })

十、Axios

详细参考文档:axios中文文档

1.在Vue中使用axios:

1).安装axios包

$ npm install axios

2).将axios绑定在Vue实例对象或者原型对象上

Vue.prototype.$axios = axios;

3).根据axios中文文档使用axios

2.axios的基本使用    (有get或post两种)

    sendAjax(){
                this.$axios.get('http://api.github.com/users')
                .then(res=>{
                    username=res.data[0].login;
                    return this.$axios.get(`http://api.github.com/users/${username}/repos`);
                })
                .then(res=>{
                    console.log(res.data);
                }).catch(err=>{
                    console.log(err);
                })
            }

注意:get方式有两种带携带参数的方式(写在url上或者以json对象形式作为参数携带) post方式有一种携携带参数方式(以json对象形式作为参数携带)

3.axios的并发请求  this.$axios.all([getD,postD]).then(res=>{}).catch(err=>{})

handleClick(e){
                    let urlDefault=`http://api.github.com/`;
                    let getD=this.$axios.get(`${urlDefault}users`)
                    let postD=this.$axios.get(`${urlDefault}`,{
                        id:111
                    })
                    this.$axios.all([getD,postD])
                    .then(this.$axios.spread((res1,res2)=>{
                        console.log(res1.data);
                        console.log(res2.data);
                    })
                    )
                    .catch(err=>{
                        console.log(err);
                    })
                }
            }

4.axios的请求和响应    transformRequest和transformResponse

        this.$axios({
                        url: `${urlDefault}users`,
                        method: 'get',
                        // `transformRequest` 允许在向服务器发送前,修改请求数据
                        transformRequest: [function (data, headers) {
                            // 对 data 进行任意转换处理
                            return data;
                        }],

                        // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
                        transformResponse: [function (data) {
                            console.log(data);//等于res.data的内容
                            return data;
                        }],
                    })
                    .then(res=>{
                        console.log(res);
                    })
                    .catch(err=>{
                        console.log(err);
                    })

5.axios拦截器

                    //添加请求拦截器
                    this.$axios.interceptors.request.use(config => {
                        console.log(config);
                        return config;
                    }, error => {
                        // 对请求错误做些什么
                        return Promise.reject(error);
                    });
                    // 添加响应拦截器
                    this.$axios.interceptors.response.use(response => {
                        console.log(`two:${response}`);
                        return response;
                    }, error => {
                        // 对响应错误做点什么
                        return Promise.reject(error);
                    });

axios拦截器实现加载动画

   //通过控制this.isShow的值控制加载动画的显示与隐藏
   handleClick(e) {
                    let urlDefault = `http://api.github.com/`;
                    /* 添加请求拦截  请求时isShow为true  显示加载动画 */
                    this.$axios.interceptors.request.use(config => {
                        this.isShow=true;
                        return config;
                    }, error => {
                        // 对请求错误做些什么
                        return Promise.reject(error);
                    });
                    /* 添加响应拦截器 响应时isShow为false  隐藏加载动画 */
                    this.$axios.interceptors.response.use(response => {
                        this.isShow=false;
                        return response;
                    }, error => {
                        // 对响应错误做点什么
                        return Promise.reject(error);
                    });
                    this.$axios({
                        url: `${urlDefault}users`,
                        method: 'get'
                    })
                    .then(res => {
                        console.log(res);
                    })
                    .catch(err => {
                        console.log(err);
                    })
                }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值