按钮组件
# 按钮组件
# 1 组件结构
这个组件除了封装按钮的类型、状态、大小等常见功能外,还增加了自定义的美观样式,并通过 SCSS
增强其灵活性。
<!-- ButtonComponent.vue -->
<template>
<button
:class="['custom-button', buttonClass]"
:disabled="disabled || loading"
@click="handleClick"
>
<!-- 如果处于加载状态,显示加载动画 -->
<span v-if="loading" class="loading-spinner"></span>
<!-- 如果没有加载,显示按钮文本 -->
<span v-else>
<slot></slot> <!-- 支持插槽自定义按钮文本 -->
</span>
</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
/**
* @description 封装的自定义按钮组件,具有美观且通用的样式,并支持多种类型和状态
* @param {String} type 按钮类型,可选值:'primary' | 'success' | 'warning' | 'danger' | 'info',默认 'primary'
* @param {String} size 按钮大小,可选值:'large' | 'medium' | 'small' | 'mini',默认 'medium'
* @param {Boolean} loading 按钮是否处于加载状态,默认 false
* @param {Boolean} disabled 按钮是否禁用,默认 false
* @emits click 按钮点击事件
*/
const props = defineProps({
type: {
type: String,
default: 'primary', // 默认类型为 primary
},
size: {
type: String,
default: 'medium', // 默认大小为 medium
},
loading: {
type: Boolean,
default: false, // 默认不加载
},
disabled: {
type: Boolean,
default: false, // 默认不禁用
},
});
// 定义按钮点击事件
const emit = defineEmits(['click']);
/**
* @description 按钮点击处理方法
* @returns {void}
*/
const handleClick = () => {
if (!props.loading && !props.disabled) {
emit('click'); // 触发父组件的 click 事件
}
};
// 动态计算按钮的样式类
const buttonClass = computed(() => {
return `${props.type} ${props.size} ${props.loading ? 'loading' : ''}`;
});
</script>
<style scoped lang="scss">
/* 基础按钮样式 */
.custom-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0 20px;
border-radius: 4px;
font-size: 14px;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
border: none;
cursor: pointer;
white-space: nowrap;
/* 按钮的交互状态 */
&:hover {
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}
&:disabled {
cursor: not-allowed;
opacity: 0.6;
}
}
/* 按钮类型样式 */
.primary {
background-color: #409eff;
color: #fff;
&:hover {
background-color: #66b1ff;
}
}
.success {
background-color: #67c23a;
color: #fff;
&:hover {
background-color: #85ce61;
}
}
.warning {
background-color: #e6a23c;
color: #fff;
&:hover {
background-color: #f3bd63;
}
}
.danger {
background-color: #f56c6c;
color: #fff;
&:hover {
background-color: #f78989;
}
}
.info {
background-color: #909399;
color: #fff;
&:hover {
background-color: #a6a9ad;
}
}
/* 按钮大小样式 */
.large {
font-size: 16px;
padding: 12px 24px;
}
.medium {
font-size: 14px;
padding: 10px 20px;
}
.small {
font-size: 12px;
padding: 8px 16px;
}
.mini {
font-size: 10px;
padding: 6px 12px;
}
/* 加载状态样式 */
.loading {
pointer-events: none;
opacity: 0.8;
}
.loading-spinner {
width: 20px;
height: 20px;
border: 2px solid rgba(255, 255, 255, 0.6);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* 加载动画 */
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# 2. 详细说明
# 2.1 属性说明
type
:- 类型:
String
- 描述:指定按钮的类型,支持
'primary'
(主要按钮)、'success'
(成功按钮)、'warning'
(警告按钮)、'danger'
(危险按钮)和'info'
(信息按钮)。 - 默认值:
'primary'
- 类型:
size
:- 类型:
String
- 描述:按钮的大小,支持
'large'
(大按钮)、'medium'
(中按钮)、'small'
(小按钮)和'mini'
(迷你按钮)。 - 默认值:
'medium'
- 类型:
loading
:- 类型:
Boolean
- 描述:是否显示加载状态。如果设置为
true
,按钮会进入加载状态,并显示一个加载动画。 - 默认值:
false
- 类型:
disabled
:- 类型:
Boolean
- 描述:是否禁用按钮。禁用状态下按钮无法点击,且样式会变为灰色。
- 默认值:
false
- 类型:
# 2.2 事件说明
click
:- 类型:
Event
- 描述:点击按钮时触发的事件,只有按钮未处于加载或禁用状态时才会触发该事件。
- 类型:
# 2.3 样式说明
- 按钮的类型、大小等都通过对应的类名动态应用。通过定义
primary
、success
、warning
、danger
、info
五种类型按钮的颜色样式,开发者可以快速创建不同风格的按钮。 - 添加了加载状态下的按钮动画(圆形旋转),并通过
SCSS
实现动画效果,使其更加美观。 - 增加了按钮的交互效果,当用户将鼠标悬停在按钮上时,会有阴影和颜色变化的过渡效果,提升用户体验。
# 3. 使用示例
在项目中引入封装的按钮组件,并通过不同的 props
来定制按钮外观和功能。
# 3.1 基本使用
<template>
<div>
<CustomButton type="primary" @click="handleClick">主要按钮</CustomButton>
<CustomButton type="success" size="large" @click="handleClick">成功按钮</CustomButton>
<CustomButton type="warning" :loading="isLoading" @click="toggleLoading">警告按钮</CustomButton>
<CustomButton type="danger" :disabled="true">禁用按钮</CustomButton>
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomButton from '@/components/ButtonComponent.vue'; // 引入自定义按钮组件
const isLoading = ref(false);
// 按钮点击事件处理
const handleClick = () => {
console.log('按钮点击');
};
// 切换加载状态
const toggleLoading = () => {
isLoading.value = !isLoading.value;
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 3.2 自定义按钮
可以通过修改 props
自定义按钮的外观和行为,例如使用圆角、加载状态、禁用状态等。
<CustomButton
type="success"
:loading="isLoading"
:round="true"
size="large"
@click="toggleLoading"
>
加载中
</CustomButton>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08