VueTypeScript按钮组件封装的具体步骤
参考课程在这:https://www.bilibili.com/video/BV1q7411i7jw?from=search&seid=115675997679082294
效果如下:
点击变小按钮
点击变大按钮并点击圆形
禁用
本文一步一步的对代码进行修改添加,并注释,最后呈现出完整代码,步骤如下:
1. 创建一个项目
2. 写一个Button.vue文件,实现按钮基础样式
3. 写一个Home.vue文件并引入注册组件
4. 通过组件传递参数并打印
5. 在Button.vue文件中对按钮添加属性,在Home.vue中进行更改使用等
一、创建一个项目
- 打开cmd
- cd到想要创建项目的文件夹
- vue create+项目名
- 进行一些配置,这里我们需要选上typescript和stylus
- cd+项目名到已创建好的项目
- node . (注意node后有一个点 . )将会自动打开vscode进入项目
创建项目后,有很多不常用的文件名,这些文件名隐藏起来能看得更清楚,具体参考这里,阅读大约需要1-2min
二、写一个Button.vue文件,实现按钮基础样式
<template>
<button class="ui-btn"> //创建按钮
<slot>button</slot> //使用插槽,默认为button
</button>
</template>
<script lang="ts">
import { Component, Vue, } from 'vue-property-decorator';
@Component
export default class Button extends Vue {}
</script>
<style lang="stylus" scoped> //添加样式
.ui-btn
width 80px
height 50px
font-size 0.875rem
padding 0 6px
border 0 solid black
// border-radius 4px
color #17233d
background-color #2d8cf0
font-weight 500
letter-spacing 0.09em
cursor pointer
user-select none
outline none
</style>
三、写一个Home.vue文件
<template>
<div class="root-home">
<div class="btn-container">
<UIButton>点这里</UIButton> //使用这个组件
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import UIButton from '@/components/UIkit/Button.vue'; //引入这个组件,名为UIButton
@Component({
components: { //注册组件UIButton
UIButton
}
})
export default class Home extends Vue {}
}
</script>
<style lang="stylus" scoped> //更改样式
.btn-container
width 480px
height 160px
display flex
justify-content center
align-items center
.btn
margin 5px
width 70px
height 45px
</style>
这个时候就可以运行出来基础样式如下:
四、通过组件传递参数并打印
在上面Button.vue文件中做添加如下,更改的部分做了注释:
<template>
<button class="ui-btn" @click="onClickBtn"> //绑定点击功能
<slot>button</slot>
</button>
</template>
<script lang="ts">
import { Component, Vue, Emit, } from 'vue-property-decorator'; //引入Emit
@Component
export default class Button extends Vue {
@Emit('click') private emitClickEvent(event: MouseEvent) {} //绑定点击事件,并传递event这个点击事件,为MouseEvent类型
private onClickBtn(event: MouseEvent){ //因为是封装组件,所以设置为private,创建点击事件,并调用emitClickEvent来传递event
this.emitClickEvent(event);
}
}
</script>
<style lang="stylus" scoped>
resize(width,height,fontSize)
width width
height height
font-size fontSize
&.ui-btn-circle
border-radius (@height / 2)
width @height
.ui-btn
resize(80px,50px,0.875rem)
padding 0 6px
border 0 solid black
// border-radius 4px
color #17233d
background-color #2d8cf0
font-weight 500
letter-spacing 0.09em
cursor pointer
user-select none
outline none
&:hover
filter brightness(125%)
&:active
filter brightness(80%)
&.ui-btn-large
resize(120px,70px,0.975rem)
&.ui-btn-min
resize(55px,26px,0.075rem)
&.ui-btn-normal
resize(80px,50px,0.875rem)
&.ui-btn-rectangle
border-radius 0
&.ui-btn-circle
border-radius (@height / 2)
&.ui-btn-disabled
background-color #f5f5f5
color #c5c8ce
cursor not-allowed
</style>
同样在上面Home.vue文件中做添加如下,更改的部分做了注释:
<template>
<div class="root-home">
<div class="btn-container">
<UIButton @click="onClick">点这里</UIButton> //绑定点击事件
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import UIButton from '@/components/UIkit/Button.vue';
@Component({
components: {
UIButton
}
})
export default class Home extends Vue {
private onClick(event: MouseEvent){ //创建一个private方法,当点击这个按钮组件时,就打印event,这里的event就是从Button.vue中传递过来的
console.log(event);
}
}
</script>
<style lang="stylus" scoped>
.btn-container
width 480px
height 160px
display flex
justify-content center
align-items center
.btn
margin 5px
width 70px
height 45px
</style>
效果如下:
五、在Button.vue文件中对按钮添加属性,在Home.vue中进行更改使用等
Button.vue文件(完整代码)中添加了变大、变小、正常、圆角、直角、禁用等属性,如下,更改的部分做了注释:
<template>
<button class="ui-btn" @click="onClickBtn"
:class="{
'ui-btn-large' : large, //绑定ui-btn-large类,在这个类中将按钮变大,当large为真,这个类就会起作用
'ui-btn-min': min, //绑定ui-btn-min类,在这个类中将按钮变小,当min为真,这个类就会起作用
'ui-btn-normal': normal, //绑定ui-btn-normal类,在这个类中将按钮变为初始的正常大小,当normal为真,这个类就会起作用
'ui-btn-rectangle': rectangle, //绑定ui-btn-rectangle类,在这个类中将按钮变成直角,当rectangle为真,这个类就会起作用
'ui-btn-circle': circle, //绑定ui-btn-circle类,在这个类中将按钮变成圆形,当circle为真,这个类就会起作用
'ui-btn-disabled': disabled //绑定ui-btn-disabled类,在这个类中将按钮禁用,当disabled为真,这个类就会起作用,这时候按钮就不能点击了
}"
>
<slot>button</slot>
</button>
</template>
<script lang="ts">
import { Component, Vue, Emit, Prop } from 'vue-property-decorator'; //引入Prop装饰器
@Component
export default class Button extends Vue {
@Prop(Boolean) private large: boolean | undefined; //注解父组件传过来的large属性
@Prop(Boolean) private min: boolean | undefined; //注解父组件传过来的min属性
@Prop(Boolean) private normal: boolean | undefined; //注解父组件传过来的normal属性
@Prop(Boolean) private rectangle: boolean | undefined; //注解父组件传过来的rectangle属性
@Prop(Boolean) private circle: boolean | undefined; //注解父组件传过来的circle属性
@Prop(Boolean) private disabled: boolean | undefined; //注解父组件传过来的disabled属性
@Emit('click') private emitClickEvent(event: MouseEvent) {}
private onClickBtn(event: MouseEvent){
this.emitClickEvent(event);
}
}
</script>
<style lang="stylus" scoped>
resize(width,height,fontSize) //这是混合写法,可以参考这篇文章,阅读大约***1***min:(https://blog.csdn.net/bubbleSweet/article/details/113002098)
width width
height height
font-size fontSize
&.ui-btn-circle
border-radius (@height / 2)
width @height
.ui-btn
resize(80px,50px,0.875rem)
padding 0 6px
border 0 solid black
color #17233d
background-color #2d8cf0
font-weight 500
letter-spacing 0.09em
cursor pointer
user-select none
outline none
&:hover
filter brightness(125%) //鼠标放在上面会高亮显示
&:active
filter brightness(80%) //点击时会暗沉
&.ui-btn-large
resize(120px,70px,0.975rem)
&.ui-btn-min
resize(55px,26px,0.075rem)
&.ui-btn-normal
resize(80px,50px,0.875rem)
&.ui-btn-rectangle
border-radius 0
&.ui-btn-circle
border-radius (@height / 2)
&.ui-btn-disabled
background-color #f5f5f5
color #c5c8ce
cursor not-allowed
</style>
Home.vue文件(完整代码)中使用变大、变小等属性属性,如下,更改的部分做了注释:**
<template>
<div class="root-home">
<div class="btn-container">
<UIButton @click="onClick"
:min = "min" //绑定min这个属性,当min为真时,min这个属性就会生效,large、normal、rectangle等都是以此类推
:large = "large"
:normal = "normal"
:rectangle = "rectangle"
:circle = "circle"
:disabled="disabled"
>点这里</UIButton>
</div>
<div class="btn-group"> //创建一组变大、变小、正常按钮
<UIButton class="btn" @click="changeSize('min')">变小</UIButton> //对按钮进行点击事件绑定,当点击这个按钮就传入min这个参数,按钮会变小,其他的按钮以此类推
<UIButton class="btn" @click="changeSize('large')">变大</UIButton>
<UIButton class="btn" @click="changeSize('normal')">正常</UIButton>
</div>
<div class="btn-group"> 创建一组直角、圆角按钮
<UIButton class="btn" @click="changeRadius('rectangle')">直角</UIButton> //绑定变成直角的点击事件,当点击就会传入rectangle这个参数,按钮变成直角,圆形也是以此类推
<UIButton class="btn" @click="changeRadius('circle')">圆形</UIButton>
</div>
<div class="btn-group"> //这里和上面一样
<UIButton class="btn" @click="changeDisabled">禁用</UIButton>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import UIButton from '@/components/UIkit/Button.vue';
@Component({
components: {
UIButton
}
})
export default class Home extends Vue {
//下面声明了一些变量的属性,默认是false
private min: boolean = false;
private large: boolean = false;
private normal: boolean = false;
private rectangle: boolean = false;
private circle: boolean = false;
private disabled: boolean = false;
//当点击事件发生,会传入相应的参数,用了switch...case,传入的参数是什么,相应的参数变成true,其他的变成false
//例如,当点击了变小这个按钮,调用changeSize('min')这个方法,传入了min这个参数,case 'min'时,this.min=true,将min置为真,large、normal为false,那么在上面的<UIButton></UIBtton>中绑定的属性中,min属性就会生效,同时还会单向的向子组件传递min的值,也就是true
private changeSize(name: string) {
switch (name) {
case 'min':
this.min = true;
this.large = false;
this. normal = false;
break;
case 'large':
this.large = true;
this. normal = false;
this.min = false;
break;
case 'normal':
this.normal = true;
this.min = false;
this.large = false;
break;
}
}
//与上面的方法逻辑相同
private changeRadius(name: string){
switch(name){
case 'rectangle':
this.rectangle = true;
this.circle = false;
break;
case 'circle':
this.rectangle = false;
this.circle = true;
break;
}
}
//与上面的方法逻辑相同
private changeDisabled(){
this.disabled = !this.disabled;
}
//与上面的方法逻辑相同
private onClick(event: MouseEvent){
if(!this.disabled){ //当disabled为false时,代表未禁用,就可以打印事件,如果disabled为true,代表禁用,那么点击这个按钮就不会打印,这个按钮没什么用
console.log(event);
}
}
}
</script>
<style lang="stylus" scoped> //给新的一组button添加样式
.btn-container
width 480px
height 160px
display flex
justify-content center
align-items center
.btn
margin 5px
width 70px
height 45px
</style>