效果图
鼠标悬浮有对应的文字提示,且图标出现背景色和颜色
实现
目前提供五个固定样式的图标及三个用户自定义的图标,可根据需要补充
组件代码
<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: BtnTypeicon?: string | undefinedcolor?: string | undefinedshow?: boolean | truetooltip?: string | undefineddisabled?: booleanhref?: 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)"
/>