vue 2.x 版本 基础知识点

Vue 是基于MVVM设计模式
是单页面应用

引入Vue代码

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

将标签绑定为Vue

el

指定一个选择器, 代表该元素中使用vue来渲染

let app = new Vue({
    el:"#app"
})//app为标签id

el支持class(以点)、标签名方式

在标签里显示数据用双大括号

Mustache 语法糖

<div class="#app">{{content}}</div>
<script> new Vue({
        el:"#app",
        data:{
            content:"内容"
        }
    })</script>

双大括号里面可以写表达式

{{true?name:age}}

Vue里的数据

data

一般数据来源后端(通过ajax请求)

var app=new Vue({
    el:"#app",
    data:{
        content:"内容"
    }
})

data里的数据可以与标签进行绑定

<div id="app">{{content}}</div>

建议写函数形式
用脚手架需要

let app = new Vue({
    el:"#app",
    data(){
        return{
            //数据
        }
    }
})

methods事件

里面存放的都是函数事件

var app=new Vue({
    el:"#app",
    data:{
        content:""
    },
    methods:{
        foo:function(){//}
    }
})

methods事件里面通过this可以访问到data里面的数据也可以访问到methods

let app=new Vue({
    el:"#app",
    data:{
        content:"内容"
    },
    methods:{
        foo:function(){
            this.content = "更改后的内容"
        }
    }
})

filters过滤

差值符号里面加上竖线 就是进行数据的判断
二次渲染

<p v-for="item in arr" :key:"item.name">
    {{item.name | goudan}}
</p>
<script>
	let app=new Vue({
    el:"#app",
    data:{
        arr:"数据"
    },
    filters:{
        goudan(v){//这个v就是差值符号里面的item
            return  "加的东西"+v //过滤后的数据
        }
    }
})
</script>

computed 简化差值符号

不能先定义在data里
将数据进行一次处理

<div id="app">
    <p>{{funl}}</p>
</div>
<script>
	let app=new Vue({
    el:"#app",
    data:{
        arr:"数据"
        ,o:"bb"
    },
    computed:{
        funl(){
            return this.arr+"."+this.o
        }
    }
})
</script>
可以写set和get
computed:{
    msg:{
        get(){
        return 2
        }
        ,set(){
            this.lie ++
        }
    }
    
}

监听数据的变化watch

要先在data里面定义
监听的数据发生变化之后这个函数会触发

data:{
    a:10
},
watch:{
    a(newVal,oldVale){//两个参数一个新值 一个旧值
        console.log(1)
    }
}

Vue的标签方式

v-text

<div id="app" v-text="content"></div>
let app=new Vue({
    el:"#app",
    data:{
        content:"内容"
    }
})

不能解析标签名,可以用字符串拼接
无论内容是什么只会解析为文本
可以用模板字符串

<div id="app" v-text=`${name}`></div>

v-cloak

当浏览器加载的数据非常庞大
加载的一瞬间会出现双大括号的差值表达式
解决这种 闪现 的现象
在需要隐藏的地方添加 v-cloak
然后再css 里面先隐藏这个标签

<div id="app" v-cloak></div>
<!-- 添加 v-cloak属性 -->
[v-cloak]{
/* css里面不进行显示 */
	display:none;
}

原理就是在页面加载的时候先不进行渲染
Vue 挂在完成之后内部进行渲染

v-html

<div id="app" v-html="content"></div>
let app=new Vue({
    el:"#app",
    data:{
        content:"<a helf="">内容</a>"
    }
})

设置元素的innerHTML
内容有html结构会被解析为标签

v-on事件/@

v-on:事件名=“方法”

<input type="button" value="事件绑定" v-on:click="foo">
<input type="button" value="事件绑定" v-on:mouseenter="foo">
<input type="button" value="事件绑定" v-on:dblclick="foo">
<input type="button" value="事件绑定" v-on:click="foo">
let app=new Vue({
    el:"#app",
    data:{
        content:"1234"
    },
    methods:{
        foo:function(){}
    }
})

methods里面写事件
v-on可以简写为@

自定义参数和事件修饰符

在方法里面传入参数
v-on:click=“foo(x)”

let app=new Vue({
    el:"#app",
    methods:{
        foo:function(x){}//这里接受参数
    }
})
键盘按下事件

@keydown.enter=“方法”
enter回车键

<div @keyup.k="方法($event)"></div><!--按K键触发事件-->

可以串联修饰

<div @keyup.k.enter.space="方法"></div>
@click.once只触发一次
只有左键触发@click.left
只有右键触发@click.right
只有中键触发@click.middle
阻止冒泡
<div @click="方法">
    <button @click.stop="方法"></button>
</div>
阻止默认事件
@click.right.prevent
<div @click.right.prevent="方法"></div>
<a href="地址"  @click.right.prevent="方法"></a><!--阻止a标签跳转-->

传入两个事件需要传对象

<div v-on="{click:方法,mouseenter:方法}"></div>
接触事件

变相取消

<div @click="ifClick && clickAdd()"></div>
<!--判断ifClick的值决定执不执行clickAdd-->

v-model

设置和获取表单元素的值(双向数据绑定)
在表单元素里面添加v-model指令在指令里面添加data里面的数据

<div id="app">
	<input type="text" v-model="content">
</div>
<script>
	let app=new Vue({
        el:"#app",
        data:{
            content:"绑定的数据"
        }
    })
</script>

无论是修改表单元素里的值还是数据里的值都会互相更改

v-show

根据表达式的真假来显示或者隐藏
true表示显示
false表示隐藏

<img v-show="true"><!--显示-->
<img v-show="12<11"><!--隐藏-->

原理是修改元素的display实现显示隐藏
指令后面的内容最终都会解析为布尔值
数据改变之后,对应元素的显示状态会同步更新

v-if

根据表达式的真假来显示或者隐藏操作的是dom元素
直接删除dom元素
性能消耗比较大
如果频繁切换用v-show
为false时从dom树中移出

v-else

配合v-if使用
如果if是false ,else就是显示
必须要紧跟v-if使用中间不能有东西

v-else-if

根据上一个v-if进行再次判断

v-bind设置元素的属性

v-bind:属性名=表达式
可以用冒号简写:

<img v-bind:src="imgSrc">
<img :src="imgSrc">
<img :class="imgClass?类名:''"><!--判断imgClass的值如果为假类名为空-->
<img :class="{类名:imgClass}">
<script>
	var app=new Vue({
        el:"#app",
        data:{
            imgSrc:"地址",
            imgClass:false
        }
    })
</script>
更改class操作
<div :class="{red:ifRed}"></div>判断ifRed的值来确定class添不添加red值
ifRed是真class就有red值
<div :class="[
             {'red':ifRed},
             'green'
             ]"></div>数组里面必须有引号不加引号就会去data里面找
style操作
<div :style="{font-size:12px}"></div>

v-for生成列表结构

根据数据生成列表结构

<ul>
    <li v-for="(item,index) in arr"> {{index}} {{item}}</li>
</ul>
<h3 v-for="item in obj"> {{item.name}} </h3>
<div v-for="(value,key,index) in o">value{{value}}key{{key}}index{{index}}</div>value是键key是值index是序号
<script>
	var app=new Vue({
        el:"#app",
        data:{
            arr:[1,2,3,4,5],
            obj:[
                {name:"张三"},
                {name:"李四"},
                {name:"王五"}
            ],
            o:{user:"名字",age:18,sex:"男"}
        }
    })
</script>

li标签里item是数组的每一项 arr是数组本身
数组的长度的更新会同步到页面上去,是响应式的

v-key顺序绑定

根v-for一块使用

<div v-for="item in arr" :key="item"></div>生成的每个div与item绑定
数组在后期进行打乱那么div也会随着数据进行移动

如果数据是对象数组就选取对象里面独一无二的属性

v-once渲染单次

v-pre不渲染

全局API

自定义指令directive

Vue.directive("goudan",(node,data)=>{//节点,数据
    //里面进行的操作
})
//或者
Vue.directive('dachui',{
    bind(){
        //指令第一次绑定时调用的函数
    },
    inserted(){
        //当被绑定的元素插入DOM中时
    },
    update(){
        //数据进行更改时
    },
    componentUpdate(){
        //
    },
    upbind(){
        //解绑
    }
})

标签里面添加v-goudan
指令里面传一个名字和函数
函数里面有两个参数
绑定的节点 , 带来的数据

extend 构造器创建子类

const goudan = Vue.extend({
    template:'<div>{{name}}</div>',
    data(){
        return{
            name:'dachui'
        }
    }
})
//挂载到#cuihua里
new goudan().$mount('#cuihua')

Vue.set

在Vue里面操作数据数组没办法改其中一个或几个值(除了更改全部或重新赋值)
只要是数组就不行对象可以
改变数组里的其中一项

methods:{
    fn(){
        Vue.set(this.arr,0,"goudan")//把arr的第0项改成goudan
    }
}
this.$set改变数组里的其中一项
methods:{
    fn(){
        this.$set(this.arr,0,"goudan")//把arr的第0项改成goudan
    }
}

this.$delete删除数组特定的某一项

this.$delete(this.arr,1)//删除下标是1的值

或者用JS splice

this.arr.splice(1,1)

DOM更新之后进行操作nextTick

DOM进行更新之后进行操作
但是你写在那个方法里面那个才触发

this.$nextTick(function(){
    console.log("DOM更新了")
})

查看版本 Vue.version

console.log(Vue.version)

组件

放在new Vue之前定义组件
组件中间不要有任何的东西

component全局组件

全局组件可以被任意组件所调用的

Vue.component(
	//组件名 , 在html里面就是用这个标签来渲染 标签里面不写东西
    "goudan",//还必须一些选项参数
    {
        //对应要生成的DOM结构
        template:`<p>内容</p>`
        ,data(){//data必须是函数
            return {
                msg:""
                ,num ++
            }
        }
        ,methods:{
            add(){
                this.num ++
            }
        }
    }
)
template 生成DOM结构

生成对应的结构
但是结构只能有一个跟标签
起的名字不能与原有的标签名重复
驼峰命名的时候在标签里面用横杠显示-
但是在组件里面不是单词第一个大写

Vue.component("goudan",{
    template:`<goudan>123456</goudan>`
})
<div>
    <goudan></goudan>
</div>

子组件

在实例里面定义

components

属性就是组件名
根组件可以调用全局组件
全局组件不能调用根组件

template
new Vue({
    el:"#app",
    components(){
        aaa:{//首先是用什么标签包起来
            template:`<div><p>组件</p></div>`
        }
    }
})
在标签里面引入子组件
is

component标签是vue自带的

<component is="aaa"></component>
<component :is="x"></component>
<script>
	new Vue({
        el:"#app",
        data:{
            x:"aaa"
        },
        components:{
            aaa:{
                template:`<div>这是组件</div>`
            }
        }
    })
</script>
template vue标签

不能写在绑定Vue实例的标签里面

<template id="f"></template>
<script>
new Vue({
    el:"#app",
    components:{
        aaa:{
            template:"#f"//和标签进行绑定
        }
    }
})
</script>
组件之间的传值
父组件给子组件传值

父组件传过去的值改变 子组件也改变

<div id="app">
   <aaaa :goudan="arr"></aaaa>
</div>

通过绑定标签属性传值
子组件接受

props 子组件接受
componente:{
    aaaa:{
        template:"#aaa"
        ,data(){
            return {}
        },
        props:["goudan"]//这里数组方式接受数据
    }
}
接受可以用对象接受
componente:{
    aaa:{
        temolate:"#aaa"
        ,data(){
            return {}
        }
        ,prop:{//对象非常像mongodb里面的表
            goudan:Array
            ,m:{
                type:String
                ,default:"这是默认值"
            }
            ,o:{
                type:String
                ,required:true//这个值是必须的
            }
        }
    }
}
子组件给父组件传值 $emit

事件里的自定义事件传值
设置的自定义事件写在组件的标签上面
不建议使用驼峰命名,建议短横线命名-

父组件里的子组件标签
<aaa @goudan="fun"></aaa>fun在父组件里写函数 ,父组件函数接受值
<script>
methods:{
    fun(data){
       //data就是传来的参数
    }
}
</script>
/*-------------下面是子组件里进行事件发射*/
<script>
methods:{
    dachui(){
       this.$emit("goudan",this.msg)//自定义事件名 ,传过来的数据
    }
}
</script>

绑定组件ref

<h1 ref="goudan"></h1>

Vue实例里面使用this.$refs获取此节点
如果在组件里使用ref那么this.$refs返回的是这个组件的实例方法

依赖注入

相当于组件的子组件传值个父组件

Vue.component("goudan",{
    template:"#goudan",
    data(){
        return{}
    },
    provide(){
        //发送数据
        return{
            goudan:'11'
        }
    }
})
Vue.component("dachui",{//另一个组件
    template:"#dachui",
    data(){
        return{}
    },
    inject:['goudan']//接受
})

耦合
改的方法更麻烦一点
数据传过来的是非响应式的

Axios

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

引入axios的地址
必须先导入再使用
使用get和set方法

axios.get("地址")//如果要查询具体的数值后面加上问号在添加属性名,等号属性值
    .then((response)=>{
    //请求数据成功的函数
    console.log(response)
    //response就是后端返回的数据
	})
    .catch(err=>{
    //请求数据失败的函数
	})

不同的地址获取的数据不同查询的方法不同
如果是表单元素(post)要在地址后面加逗号,在用对象的方式输入数值

    axios.post("地址",{username:"名称"})
    .then((response)=>{
        //请求数据成功的函数
    }).catch((err)=>{
        //请求数据失败的函数
    })

组件里面调用

下载axios
npm i axios -S

Axios单独放一个js文件里

import axios from "axios";
//配置默认的参数
axios.defaults.baseURL = 'http://localhost:3000';//默认访问地址
axios.defaults.withCredentials = true;//跨域允许携带cookie
axios.defaults.headers.post["Content-Type"] = "application/x-www-from-urlencoded";//设置post请求格式

使用axios
一种是全部引用
将所有的接口都引用

export default axios

使用

import request from '../api/index'
request.post("/articleInfo").then(data=>{console.log(data);}//articleInfo是地址
//post是请求方法

另一种方法是按需引用
导出的时候导出一个对象

export default {
  goudan(){//标签
    return axios.post("/articleInfo")//articleInfo是地址post是请求方法
  }
};

使用
不支持解构

import axios from '../../api';
let goudan = axios.goudan;
created() {
      goudan()
          .then(res=>{
            res.data.data;//data.data就是返回的数据
          })
    }

支持解构

export function goudan(){
    return axios.get("地址")
}

使用

import {goudan} from '../../api';

new vue

new vue返回一个实例化后的东西

let vm = new Vue({
    el:"#app",
    data:{
        content:"123"
    }
})
//

created渲染DOM之前执行函数

使用JQuery

npm i jquery -S//安装jquery

再导入

import $ from 'jquery'
//原型里添加$方法
Vue.prototype.$ = $

引入css文件

@import url("地址")

引入js文件

import "地址"//不用命名

脚手架

npm i webpack -g
npm i webpack-cli -g

建议用cmd启动脚手架

npm i @vue/cli -g

检测版本

vue -V//斜杠后面是大写的v

创建

vue create 项目名 //创建项目文件

多选 选择是空格

或者是vue ui一个ui界面

在js里面导入

import "名字" from "地址"

导出

export default "导出的东西"

启动项目

npm run sever

打包项目

npm run build
打包注意事项

如果打包后放到路由的子路径
需要注意
在根目录创建vue.config.js 文件
写上如下代码

module.exports = {
    publicPath:'./'
}

如果安装了前端路由请参照
https://www.cnblogs.com/zsg88/articles/12557862.html 进行更改

插槽

在你的组件写上slot标签
他不是一个正常的html标签所以插槽本身不会渲染

<slot></slot>

使用插槽之后 组件中间可以写东西了
顺序按照设置的属性
在插槽之后用差值符号数据就是App的数据/根组件的数据
如果同个插槽显示不同内容 给插槽起名字

<slot name="defalut"></slot>默认是defalut
<slot name="goudan"></slot>
<slot name="dachui"></slot>

显示指定插槽内容用template标签

v-slot/#

简写是#号

<template v-slot:goudan>
	<p>我是第一段内容</p>
</template>
<template #dachui>
	<p>我是第二段内容</p>
</template>

可以用于传值

<slot :goudan="msg" :dachu="gg" :name="goudan"></slot>
/使用
<template v-slot:goudan="{msg,gg}">
	<p>我是第一段内容</p>
</template>
///或者是
<template #goudan="{msg,gg}">
	<p>我是第一段内容</p>
</template>

生命周期函数

一个组件的生命周期里做的一些事情

beforeCreate() 实例化之后 观测数据之前

created()开始检测数据

beforeMount()在页面即将渲染之前

在渲染和实例挂载之间 去调用子组件 完成子组件的生命周期

mounted()实例被挂载之后

beforeUpdate()数据更新之前

update()数据更新之后

activated()路由激活

<keyy-alive>
	将组建写在这里 保存到缓存里面
    节省性能
</keyy-alive>

deactivated()注销

上面两个需要keyy-alive标签才会触发

beforeDestroy()消失之前

组件消失

destroyed()消失之后

组件重新显示

UI组件

下载

引入

//全局
impot {Button} from "Vant"
Vue.use(Button)
//局部 局部需要下载插件
impot {Button} from "Vant"
export default {
    components:{
        [Button.name]:Button//用它组件里面的name
    }
}
Vue add element-ui

前端路由

需要Router

有两种
一个是默认的hash路由
一个是history
默认的路由地址上多一个#号
目的是判断是否是前端路由

history路由
路径就没有#号
但是他的路由容易跟后端冲突
比如 前端有一个/adou路由 后端有一个/adou路由 一旦刷新页面就出错
后端需要设置get路由返回同一个HTML文件

切换模式就是更改router 下面的index文件

const router = new VueRouter({
    mode:"history",//默认是hash路由 ,就是带#号的
  	routes
});

export default router

配置路由

先引用
在router文件里面的index引用你写的页面

router = [
    path:"/",
    name:"Home",
    component:import("页面文件")
]

404页面就是星号 找不到路由

path:"*",
name:"404"

然后在页面里面引入标签
to就是你跳转的链接

<router-link to="/goudan">跳转</router-link>跳转的标签
<router-view/>跳转时渲染的地方

编程式路由 $router

push go replace
this.$router.push("/")//添加一个当前的新历史 浏览记录
this.$router.go(-1)//当前页面向前访问 正数是向后
this.$router.replace("/")//替换当前浏览的记录
push 的操作
//可以传对象
this.$router.push({path:'/foo1',query:{name:'goudan'}})//query是参数

子路由children

在配置路由的地方需要的地方写上属性
children
是一个数组

[
    {
        path:"/",
        name:"Home",
        component:""
    },{
        path:"/about",
        name:"about",
        component:"",
        children:[//拥有子路由
            {
                path:"all",
                name:"All",
                component:"文件路径"
            }
        ]
    }
]

渲染就跟原来的一样
但是在写router-link标签的时候注意
里面的to属性浏览器里的地址怎么写你就怎么写

<router-link to="/about/all"></router-link>

如果想默认就出现一个子路由
他的路由里面的path就为空path:""

在router-link标签里面的to可以进行筛选路由

<router-link :to={name:"All"}></router-link>
找到路由里面name是All的路由

但是路由的命名时会冲突的

别名

路由里面path有一个别名
他既可以有这个名字又可以有另一个名字

{
    path:"",//在子路由里path不写意思指默认显示这个页面
    alias:"all",
    name:"All",
    component:()=>import("路径")
}

路由传参$ruote

参数在query里面

mounted(){
    this.$route.query
}
动态路由params

在路由里面设置

{
    path:"about/:id"
}

请求链接的时候可以带上about/2222

获取用params

mounted(){
    this.$route.params
}

路由是守卫

next括号里面可以写false

全局守卫

main.js里面写

全局前置守卫

切换完成之前

监听前端所有路由的变化
触发内部的函数
只要路由切换就触发函数

router.beforeEach((to,from,next)=>{
    //to从哪那个路由来
    //from到那个路由去
    //next放行(相当于保安放行)
    router.path("/")
    next()
})
全局后置守卫

切换路由后
没有next因为你己经进入了那个页面

router.afterEach((to,from)=>{
    //to从哪那个路由来
    //from到那个路由去
})

局部守卫

在路由配置里面添加在你想要添加的页面

在某个单独的页面设置守卫
beforeEnter

{
    path:"/about",
    beforeEnter(to,from,next){
        //to从哪那个路由来
        //from到那个路由去
    }
}

组件内的守卫

能够监听到路由的变化

监听路由的进入

beforeRouteEnter
因为在渲染之前执行所以监听不到this
需要使用到this的话在next里写函数
但是注意每次进入到路由里会重新渲染数据

data(){
    return{
        msg:0
    }
}
,beforeRouterEnter(to,from,next){
    next(vm=>{
        vm.msg++
    })
}
监听路由的变化

beforeRouteUpdate
路由传入的参数变化触发函数

data(){
    return{
        msg:0
    }
}
,beforeRouterUpdate(to,from,next){
    next(vm=>{
        vm.msg++
    })
}
监听路由离开

beforeRouteLeave
离开此页面触发

data(){
    return{
        msg:0
    }
}
,beforeRouterLeave(to,from,next){
    
}

路由切换动画

transition标签

<transition name="goudan">
	<router-view class='dachui'/>
</transition>

设定一个name在style里面写样式

<style>
    .dachui{
        transsition: 2s;
    }
    进入的状态
    .goudan-enter{
        进入的初始状态
        opacity:0;
    }
    .goudan-enter-active{
        进入动画过程中
    }
    .goudan-enter-to{
        进入的结束状态
        opacity:1;
    }
    离开的状态
    .goudan-leave{
        离开的初始状态
        opacity:1;
    }
    .goudan-leave-to{
        离开的结束状态
        opacity:0;
    }
</style>

Vuex

多了一个store文件
相当于一个仓库, 存储变量
方便组件之间进行通讯

state: 状态

组件都能使用的一些数据
使用方法:

<h2>
    {{$store.state.num}}
</h2>
<script>
	export default {
        name:"Home",
        methods:{
            fn(){//不要这么写 仓库只能使用不能更改 
                //需要更改就写 方法
                this.$store.state.num ++
            }
        }
    }
</script>

但是一般这个使用方法名字太长了
可以使用computed方法

computed:{
    num(){
        return this.$store.state.num
    }
}

这样可以直接使用{{num}}来书写

如果还是麻烦可以用vuex里的mapState

mapState

他是一个函数需要执行
函数执行需要传入参数 ,传入你需要的变量数组的形式传入

import {mapState} from 'Vuex';
export default {
    name:"Home",
    computed:mapState(['num','goudan'])
}

mpaState执行之后返回一个对象 ,对象里面是你需要的数据 但是
每个数据是一个函数
所以要写到computed里面
computed里面的变量都是一个函数形式

但是如果你要在computed里写自己的方法就不好写了
可以使用ES6的…解构

computed:{
    dachui(){
        return 2+"";
    },
    ...mapState(['num','goudan'])
}

getters

相当于computed

getters:{
    goudan(state){
        return state.num +''//state是上面的vuex里的state
    }
}

getters和state的关系相当于computed和data的关系

mutations 定义方法

定义操作state的方法 (里面写同步方法)

mutations:{
    addN(state){
        state.num ++
    }
}
使用方法$store.commit
<button @click='$store.commit("addN")'>按钮</button>

如果觉得名字太长可以调用mapMutations
在mathods里面挂载

mathods:{
    ...mapMutations(['addN'])
}

使用:

<button @click='addN(2)'></button>
mutations:{
    addN(state,n){
        state.num += n
    }
}

actions 异步的方法

存放异步操作

actions:{
    addAsync(context){
        new Promise(req=>{
            setTimeout(req,1000);
        }).then(()=>{
            context.commit('addN')
        })
    }
}

$store.dispath方法小范围使用
...mapActions([])进行使用

modules 模块

将一些状态模块化
将一些定义的变量和相关的额方法写到一个对象里面

const num = {
    namespaced:true,
    state:{
        num:1
    },
    mutations:{},
    actions:{}
}

namespaced创建一个命名空间
可以用一个变量名去接受他

然后添加到modules里面

modules:{
    num:num
}

在导入数据的时候加上名字
mapState('num',['num'])

APP里路由的变化监听

watch:{
    $route(){//watch监听
        //监听route的变化
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值