vue3 封装一个按钮组件(可自定义按钮样式)

效果图

鼠标悬浮有对应的文字提示,且图标出现背景色和颜色

 

实现

目前提供五个固定样式的图标及三个用户自定义的图标,可根据需要补充

组件代码

<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)"
/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/303570.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

jupyter内核错误

1、在dos窗口输入以下命令激活环境&#xff1a;anaconda activate 【py环境名&#xff0c;比如py37】&#xff08;目的是新家你一个虚拟环境&#xff09; 2、在虚拟环境py37下安装jupyter notebook&#xff0c;命令&#xff1a;pip install jupyter notebook 3、安装ipykerne…

python24.1.8

嵌套/多条件判断 嵌套 多条件&#xff1a; 实践&#xff1a;

pybind11实现numpy和OpenCV Mat的数据交互

1、编译安装pybind11 下载源代码&#xff1a;https://github.com/pybind/pybind11&#xff0c; 文档&#xff1a;https://pybind11.readthedocs.io/en/stable/compiling.html 解压后进入到命令行&#xff0c;如果有conda环境&#xff0c;就先进入想要的conda环境&#xff0c…

【python入门】day22:机票订购界面、北京地铁1号线运行图

机票订购界面 print(✈国内\t✪国际&#xff0c;港澳台\t↘发现低价) print(----------------------------------) print(航班类型&#xff1a;⊙单程 ⊙往返 ⊙多程&#xff08;含缺口程&#xff09;) print(出发城市&#xff1a;北京) print(到达城市&#xff1a;长春) pri…

OpenHarmony - 基于ArkUI框架实现日历应用

前言 对于刚刚接触OpenHarmony应用开发的开发者&#xff0c;最快的入门方式就是开发一个简单的应用&#xff0c;下面记录了一个日历应用的开发过程&#xff0c;通过日历应用的开发&#xff0c;来熟悉基本图形的绘制&#xff0c;ArkUI的组件的使用&#xff0c;UI组件生命周期&a…

Java集合框架概念详解

目录 1. 什么是Java集合框架&#xff1f;2. 常用接口介绍3. 常用实现类介绍4. 集合框架的应用场景 前言&#xff1a; Java集合框架是Java编程中最重要的工具之一。它提供了一套强大而灵活的数据结构和算法&#xff0c;用于存储和操作数据。本文将详细介绍Java集合框架的概念、常…

前端算法总结

基础–时间复杂度&空间复杂度 什么是复杂度分析 &#xff1f;为什么要进行复杂度分析 &#xff1f;如何进行复杂度分析 &#xff1f; 双指针 最接近的三数之和通过删除字母匹配到字典里最长单词 滑动窗口 滑动窗口的最大值 二叉树 二叉树的最近公共祖先 堆 最小的k个数前 K…

Vant2组件库van-list+Toast下拉加载滚动条回顶问题

目录 List 列表 Toast 轻提示 解决方案 1、不使用 Toast 的 加载提示 2、修改调整 pointer-event 属性值 3、判断是否为第一次加载再使用 背景 &#xff1a; 移动端项目 开发时&#xff0c;有数据长列表展示的场景需求&#xff0c;此时就用到了 Vant2 组件库里面的 <v…

结构型设计模式——外观模式

外观模式 有句话说这个世界就是个草台班子&#xff0c;只不过排面做的好看而已&#xff0c;里面都是一包糠。这句话来形容外观模式非常准确&#xff0c;外观模式又叫门面模式&#xff0c;顾名思义一个系统我不管你里面有多复杂有多少屎山代码&#xff0c;我只要求你提供的接口…

使用JGit拉取代码提示未授权not authorized

原因&#xff1a;2021年8月13日后不支持密码登录&#xff0c;需要使用token验证 调用时候需要先去git仓库创建个人令牌 需要在安全中心创建个人token&#xff0c;使用token名称作为账号&#xff0c;使用token作为密码。 另&#xff1a; Github克隆仓库的三种方式对比&#xff…

Qt连接数据库(内含完整安装包)

遇到问题必须多思考 这里是最全的Qt连接数据库步骤 qt下载地址 链接&#xff1a;https://pan.baidu.com/s/1wdnTfyL9MQlNOCrSmIOxrQ?pwddgqi 提取码&#xff1a;dgqi --来自百度网盘超级会员V1的分享 数据库百度网盘地址 链接&#xff1a;https://pan.baidu.com/s/1orCczey…

Python+Flask+MySQL的图书馆管理系统【附源码,运行简单】

PythonFlaskMySQL的图书馆管理系统【附源码&#xff0c;运行简单】 总览 1、《的图书馆管理系统》1.1 方案设计说明书设计目标需求分析工具列表 2、详细设计2.1 登录2.2 注册2.3 程序主页面2.4 图书新增界面2.5 图书信息修改界面2.6 普通用户界面2.7 其他功能贴图 3、下载 总览…

c++学习:STL库(框架)+字符串模板类string+vector容器+list链表

目录 stl库 常用组件包括 字符串库 字符串模板类string 头文件 最常用的字符串模板类 字符串类型 模板原型 模板的成员数据类型 模板成员函数 有些函数会有重载&#xff0c;可以去下面网址查看std::basic_string - cppreference.comhttps://zh.cppreference.com/w/cp…

探索C语言中的水仙花数及其计算方法

在计算机科学与数学的交叉领域中&#xff0c;有一种特殊的整数被称为“水仙花数”&#xff0c;它是指一个三位数&#xff0c;其各位数字立方和等于该数本身。例如&#xff0c;153是一个典型的水仙花数&#xff0c;因为1 5 3 1 125 27 153。 下面&#xff0c;我们通过一段…

NODE笔记 0

一些简单的node学习笔记记录&#xff0c;是Vue等前端框架的基础 入门学习备忘录 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 node.js 内置网络服务器&#xff0c;是前端框架学习的基础&#xff1a; 概念&#xff1a;…

Pytorch框架学习笔记

官网- PyTorch Tensor 构造随机初始化矩阵 xtorch.rand(5,3) 构造全0矩阵&#xff0c;数据类型为long xtorch.zeros&#xff08;5,3,dtypetorch.long&#xff09; 获取维度信息 x.size(&#xff09; tensor加法 torch.add&#xff08;x&#xff0c;y&#xff09; xy y…

linux常见操作,and一些练习题加线上练习网站,无须配置linux.持续更新中。。。。

文章目录 cd命令相对路径特殊的路径表达符和cd一起使用pwdmore 查看文件内容支持翻页小技巧clear用户&#xff0c;用户权限 and 用户的切换如何创建用户 ls和通配符的使用利用通配符 *grep 过滤管道符 |如何学习Linux在线练习网站 https://www.lanqiao.cn/courses/1 cd命令 cd…

【QML COOK】- 004-添加动画

1. 编辑main.qml import QtQuickWindow {width: 800height: 800visible: truetitle: qsTr("Hello World")Image {id: backgroudanchors.fill: parentsource: "qrc:/Resources/Images/arrow.png"Behavior on rotation {NumberAnimation {duration: 1000}}}…

IntelliJ IDEA远程查看修改Ubuntu上AOSP源码

IntelliJ IDEA远程查看修改Ubuntu上的源码 本人操作环境windows10,软件版本IntelliJ IDEA 2023.2.3&#xff0c;虚拟机Ubuntu 22.04.3 LTS 1、Ubuntu系统安装openssh 查看是否安装&#xff1a; ssh -V 如果未安装&#xff1a; sudo apt install openssh-server # 开机自启…

建模软件Rhinoceros mac介绍说明

Rhinoceros mac是一款3D设计软件“犀牛”&#xff0c;在当今众多三维建模软件中&#xff0c;Rhinoceros 版因为其体积小、功能强大、对硬件要求低而广受欢迎&#xff0c;对于专业的3D设计人员来说它是一款不错的3D建模软件&#xff0c;Rhinoceros Mac中文版能轻易整合3DS MAX与…
最新文章