效果图
鼠标悬浮有对应的文字提示,且图标出现背景色和颜色
实现
目前提供五个固定样式的图标及三个用户自定义的图标,可根据需要补充
组件代码
<script setup lang="ts">
import { onMounted, PropType, reactive, ref, watch } from 'vue'
import Tooltip from '@/components/Tooltip/src/Tooltip.vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
enum BtnType {
edit = 'edit',
detail = 'detail',
delete = 'delete',
permission = 'permission',
password = 'password',
custom1 = 'custom1',
custom2 = 'custom2',
custom3 = 'custom3'
}
interface BtnAction {
type: BtnType
icon?: string | undefined
color?: string | undefined
show?: boolean | true
tooltip?: string | undefined
disabled?: boolean
href?: string | undefined
}
const props = defineProps({
actions: {
default: () => [],
type: Array as PropType<BtnAction[]>
}
})
const _actions = ref(props.actions)
// 监听数据变化
watch(
() => props.actions,
(newVal) => {
_actions.value = newVal
},
{ deep: true, immediate: true }
)
const getNormalIcon = (action: BtnAction, i: number) => {
switch (action.type) {
case BtnType.edit:
_actions.value[i].tooltip = t('common.edit')
return 'svg-icon:v2-List-write_line'
case BtnType.detail:
_actions.value[i].tooltip = t('queueCalls.details')
return 'svg-icon:v2-List-Contact_line'
case BtnType.delete:
if (!_actions.value[i].tooltip) {
_actions.value[i].tooltip = t('common.delete')
}
return 'svg-icon:v2-List-delete_line'
case BtnType.permission:
if (!_actions.value[i].tooltip) {
_actions.value[i].tooltip = t('manage.user.viewPermissions')
}
return 'svg-icon:v2-List-Authority_line'
case BtnType.password:
if (!_actions.value[i].tooltip) {
_actions.value[i].tooltip = t('login.reset.ok')
}
return 'svg-icon:v2-List-ResetPassword_line'
default:
return action.icon
}
}
const getActiveIcon = (action: BtnAction) => {
switch (action.type) {
case BtnType.edit:
return 'svg-icon:v2-List-write_face'
case BtnType.detail:
return 'svg-icon:v2-List-Contact_face'
case BtnType.delete:
return 'svg-icon:v2-List-delete_face'
case BtnType.permission:
return 'svg-icon:v2-List-Authority_face'
case BtnType.password:
return 'svg-icon:v2-List-ResetPassword_face'
default:
return action.icon
}
}
// 根据类型获取点击事件
const getClick = (type: BtnType) => {
switch (type) {
case BtnType.edit:
return 'click:edit'
case BtnType.detail:
return 'click:detail'
case BtnType.delete:
return 'click:delete'
case BtnType.permission:
return 'click:permission'
case BtnType.password:
return 'click:password'
case BtnType.custom1:
return 'click:custom1'
case BtnType.custom2:
return 'click:custom2'
case BtnType.custom3:
return 'click:custom3'
default:
return ''
}
}
const isCustom = (type: BtnType) => {
return type.indexOf('custom') !== -1
}
// const disableTooltip = (action: BtnAction) => {
// return action.tooltip === undefined || action.tooltip === ''
// }
onMounted(() => {
// 如果show为false,移除该按钮
// _actions.value = props.actions.filter((action) => action.show)
// console.log('====================', _actions)
})
const emit = defineEmits([
'click:edit',
'click:detail',
'click:delete',
'click:permission',
'click:password',
'click:custom1',
'click:custom2',
'click:custom3'
])
</script>
<template>
<div class="actions flex items-center tooltip-append">
<div v-for="(action, i) in _actions as BtnAction[]" :key="action.type">
<Tooltip :title="action.tooltip" :disabled="!action.tooltip">
<v-btn
:disabled="action.disabled === undefined ? false : action.disabled"
v-if="action.show === undefined ? true : action.show"
:href="action.href"
target="_blank"
v-bind="props"
rounded="xl"
class="default-btn mr-16px"
:class="{
'delete-btn': action.type === 'delete',
'custom-btn': isCustom(action.type)
}"
@click="emit(getClick(action.type))"
size="32"
variant="text"
color="#c6c8cd"
icon
>
<Icon size="21" class="active-icon" :icon="getActiveIcon(action)" />
<Icon size="21" class="normal-icon" :icon="getNormalIcon(action, i)" />
</v-btn>
</Tooltip>
</div>
</div>
</template>
<style scoped lang="scss">
.actions {
.default-btn:hover {
color: var(--el-color-primary) !important;
cursor: pointer !important;
}
.delete-btn:hover {
color: #db4b4b !important;
}
.custom-btn:hover {
color: var(--el-color-primary) !important;
}
}
.tooltip-append {
.active-icon {
display: none;
}
.normal-icon {
display: block;
}
}
.tooltip-append:hover {
.active-icon {
display: block;
}
.normal-icon {
display: none;
}
}
</style>
使用方法
图标数据传一个BtnAction数据格式的数组,使用默认提供的图标,只要一个type字段就可以
click事件根据对应图标类型写@click:[type]
const actions = [
{ type: 'edit' },
{
type: 'custom1',
tooltip: t('common.copy'),
icon: 'ph:copy'
},
{
type: 'custom2',
tooltip: t('common.export'),
icon: 'svg-icon:v2-arrow_download'
},
{ type: 'delete' }
] as any[]
<ActionBtn
:actions="actions"
@click:edit="editFlowTest(row)"
@click:custom1="copyFlow(row)"
@click:custom2="exportFlow(row)"
@click:delete="deleteFlow(row)"
/>