
1 changed files with 164 additions and 156 deletions
@ -1,161 +1,169 @@ |
|||||
<template> |
<template> |
||||
<button |
<button |
||||
class="hover-button" |
class="hover-button" |
||||
:class="{ 'hover-effect': hoverEffect }" |
:class="{ 'hover-effect': hoverEffect }" |
||||
@mouseenter="isHovered = true" |
@mouseenter="isHovered = true" |
||||
@mouseleave="isHovered = false" |
@mouseleave="isHovered = false" |
||||
@click="$emit('click')" |
@click="handleClick" |
||||
|
type="button" |
||||
|
> |
||||
|
<!-- 图片/图标部分 --> |
||||
|
<div class="button-icon"> |
||||
|
<slot name="icon"> |
||||
|
<img |
||||
|
v-if="defaultIcon || hoverIcon" |
||||
|
:src="isHovered && hoverIcon ? hoverIcon : defaultIcon" |
||||
|
:alt="iconAlt" |
||||
|
/> |
||||
|
<span v-else class="default-icon-placeholder"></span> |
||||
|
</slot> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 文字部分 --> |
||||
|
<span |
||||
|
class="button-text" |
||||
|
:style="{ |
||||
|
color: isHovered && hoverTextColor ? hoverTextColor : defaultTextColor |
||||
|
}" |
||||
> |
> |
||||
<!-- 图片/图标部分 --> |
<slot>{{ buttonText }}</slot> |
||||
<div class="button-icon"> |
</span> |
||||
<slot name="icon"> |
</button> |
||||
<img |
</template> |
||||
v-if="defaultIcon || hoverIcon" |
|
||||
:src="isHovered && hoverIcon ? hoverIcon : defaultIcon" |
<script> |
||||
:alt="iconAlt" |
export default { |
||||
/> |
name: 'HoverButton', |
||||
<span v-else class="default-icon-placeholder"></span> |
props: { |
||||
</slot> |
// 按钮文字 |
||||
</div> |
buttonText: { |
||||
|
type: String, |
||||
<!-- 文字部分 --> |
default: '按钮' |
||||
<span |
|
||||
class="button-text" |
|
||||
:style="{ |
|
||||
color: isHovered && hoverTextColor ? hoverTextColor : defaultTextColor |
|
||||
}" |
|
||||
> |
|
||||
<slot>{{ buttonText }}</slot> |
|
||||
</span> |
|
||||
</button> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
name: 'HoverButton', |
|
||||
props: { |
|
||||
// 按钮文字 |
|
||||
buttonText: { |
|
||||
type: String, |
|
||||
default: '按钮' |
|
||||
}, |
|
||||
// 默认图标 |
|
||||
defaultIcon: { |
|
||||
type: String, |
|
||||
default: '' |
|
||||
}, |
|
||||
// 悬停图标 |
|
||||
hoverIcon: { |
|
||||
type: String, |
|
||||
default: '' |
|
||||
}, |
|
||||
// 图标alt文本 |
|
||||
iconAlt: { |
|
||||
type: String, |
|
||||
default: '按钮图标' |
|
||||
}, |
|
||||
// 默认文字颜色 |
|
||||
defaultTextColor: { |
|
||||
type: String, |
|
||||
default: '#333333' |
|
||||
}, |
|
||||
// 悬停文字颜色 |
|
||||
hoverTextColor: { |
|
||||
type: String, |
|
||||
default: '#007bff' |
|
||||
}, |
|
||||
// 是否启用悬停效果 |
|
||||
hoverEffect: { |
|
||||
type: Boolean, |
|
||||
default: true |
|
||||
}, |
|
||||
// 按钮类型 (primary, danger, success等) |
|
||||
type: { |
|
||||
type: String, |
|
||||
default: 'default', |
|
||||
validator: value => ['default', 'primary', 'danger', 'success', 'warning'].includes(value) |
|
||||
} |
|
||||
}, |
}, |
||||
data() { |
// 默认图标 |
||||
return { |
defaultIcon: { |
||||
isHovered: false |
type: String, |
||||
} |
default: '' |
||||
|
}, |
||||
|
// 悬停图标 |
||||
|
hoverIcon: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
// 图标alt文本 |
||||
|
iconAlt: { |
||||
|
type: String, |
||||
|
default: '按钮图标' |
||||
|
}, |
||||
|
// 默认文字颜色 |
||||
|
defaultTextColor: { |
||||
|
type: String, |
||||
|
default: '#333333' |
||||
|
}, |
||||
|
// 悬停文字颜色 |
||||
|
hoverTextColor: { |
||||
|
type: String, |
||||
|
default: '#007bff' |
||||
|
}, |
||||
|
// 是否启用悬停效果 |
||||
|
hoverEffect: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 按钮类型 (primary, danger, success等) |
||||
|
type: { |
||||
|
type: String, |
||||
|
default: 'default', |
||||
|
validator: value => ['default', 'primary', 'danger', 'success', 'warning'].includes(value) |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isHovered: false |
||||
|
} |
||||
|
}, |
||||
|
methods:{ |
||||
|
handleClick(e) { |
||||
|
e.preventDefault(); |
||||
|
e.stopPropagation(); |
||||
|
this.$emit('click', e); |
||||
} |
} |
||||
} |
} |
||||
</script> |
} |
||||
|
</script> |
||||
<style scoped> |
|
||||
.hover-button { |
<style scoped> |
||||
font-family: Microsoft YaHei UI; |
.hover-button { |
||||
display: inline-flex; |
font-family: Microsoft YaHei UI; |
||||
align-items: center; |
display: inline-flex; |
||||
justify-content: center; |
align-items: center; |
||||
padding: 8px 16px; |
justify-content: center; |
||||
border: 1px solid #ddd; |
padding: 8px 16px; |
||||
border-radius: 4px; |
border: 1px solid #ddd; |
||||
background-color: white; |
border-radius: 4px; |
||||
cursor: pointer; |
background-color: white; |
||||
transition: all 0.3s ease; |
cursor: pointer; |
||||
font-size: 14px; |
transition: all 0.3s ease; |
||||
outline: none; |
font-size: 14px; |
||||
background: #F2F3F5; |
outline: none; |
||||
border: 1px solid #BABDC2; |
background: #F2F3F5; |
||||
} |
border: 1px solid #BABDC2; |
||||
|
} |
||||
.hover-button.hover-effect:hover { |
|
||||
background: #F2F7FF; |
.hover-button.hover-effect:hover { |
||||
border-color: #006AFF; |
background: #F2F7FF; |
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
border-color: #006AFF; |
||||
} |
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
||||
|
} |
||||
/* 按钮类型样式 */ |
|
||||
.hover-button.primary { |
/* 按钮类型样式 */ |
||||
background-color: #007bff; |
.hover-button.primary { |
||||
border-color: #007bff; |
background-color: #007bff; |
||||
color: white; |
border-color: #007bff; |
||||
} |
color: white; |
||||
|
} |
||||
.hover-button.danger { |
|
||||
background-color: #dc3545; |
.hover-button.danger { |
||||
border-color: #dc3545; |
background-color: #dc3545; |
||||
color: white; |
border-color: #dc3545; |
||||
} |
color: white; |
||||
|
} |
||||
.hover-button.success { |
|
||||
background-color: #28a745; |
.hover-button.success { |
||||
border-color: #28a745; |
background-color: #28a745; |
||||
color: white; |
border-color: #28a745; |
||||
} |
color: white; |
||||
|
} |
||||
.hover-button.warning { |
|
||||
background-color: #ffc107; |
.hover-button.warning { |
||||
border-color: #ffc107; |
background-color: #ffc107; |
||||
color: #212529; |
border-color: #ffc107; |
||||
} |
color: #212529; |
||||
|
} |
||||
/* 图标样式 */ |
|
||||
.button-icon { |
/* 图标样式 */ |
||||
display: inline-flex; |
.button-icon { |
||||
align-items: center; |
display: inline-flex; |
||||
margin-right: 8px; |
align-items: center; |
||||
} |
margin-right: 8px; |
||||
|
} |
||||
.button-icon img { |
|
||||
width: 20px; |
.button-icon img { |
||||
height: 20px; |
width: 20px; |
||||
transition: opacity 0.3s ease; |
height: 20px; |
||||
} |
transition: opacity 0.3s ease; |
||||
|
} |
||||
.default-icon-placeholder { |
|
||||
display: inline-block; |
.default-icon-placeholder { |
||||
width: 20px; |
display: inline-block; |
||||
height: 20px; |
width: 20px; |
||||
background-color: #ddd; |
height: 20px; |
||||
border-radius: 50%; |
background-color: #ddd; |
||||
} |
border-radius: 50%; |
||||
|
} |
||||
/* 文字样式 */ |
|
||||
.button-text { |
/* 文字样式 */ |
||||
transition: color 0.3s ease; |
.button-text { |
||||
} |
transition: color 0.3s ease; |
||||
</style> |
} |
||||
|
</style> |
Loading…
Reference in new issue