Vue3按钮组件(Button)

news/2024/7/10 0:23:46 标签: typescript, vue, less

可自定义设置以下属性:

  • 按钮默认文本(name),默认不设置时显示为'按钮'

  • 按钮类型(type),默认'default',另外可选'primary' 'danger'

  • 按钮悬浮变化效果(effect),只有type为default时,reverse才生效

  • 按钮尺寸(size),默认'middle',另外可选'small' 'large'

  • 按钮宽度(width),默认0

  • 按钮高度(height),默认40px

  • 按钮圆角(borderRadius),默认4px

  • 按钮跳转目标URL地址(route),默认{},格式与<router-link>的to属性一致(只要未设置时才可监听click事件)

  • 按钮如何打开目标URL,设置route时才起作用,默认'_self'

  • 按钮是否禁用(disabled),默认false

  • 是否将按钮设置为块级元素并居中展示(center),默认false

效果如下图:

①创建按钮组件Button.vue

<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  name?: string, // 按钮默认文本
  type?: string, // 按钮类型
  effect?: string, // 按钮悬浮变化效果,只有type为default时,reverse才生效
  size?: string, // 按钮尺寸
  width?: number, // 按钮宽度
  height?: number, // 按钮高度
  borderRadius?: number, // 按钮圆角
  route?: object, // 按钮跳转目标URL地址
  target?: string, // 按钮如何打开目标URL,设置route时才起作用
  disabled?: boolean, // 按钮是否禁用
  center?: boolean, // 是否将按钮设置为块级元素并居中展示
}
const props = withDefaults(defineProps<Props>(), {
  name: '按钮', // string 或 v-slot
  type: 'default', // 'default' 'primary' 'danger'
  effect: 'fade', //  'fade' 'reverse'
  size: 'middle', // 'small' 'middle' 'large'
  width: 0, // 默认0时自适应内容的宽度
  height: 40,
  borderRadius: 4,
  route: () => { return {} },
  target: '_self',
  disabled: false,
  center: false
})
const isRoute = computed(() => {
  if (JSON.stringify(props.route) === '{}') {
    return false
  } else {
    return true
  }
})
</script>
<template>
  <span :class="['m-button', {'center': center}]">
    <router-link
      v-if="isRoute"
      :to="route"
      :target="target"
      :disabled="disabled"
      class="u-button fade"
      :class="[type, size, {[effect]: type === 'default', widthType: width, disabled: disabled}]"
      :style="{borderRadius: borderRadius + 'px', width: (width - 2) + 'px', height: (height - 2)+'px', lineHeight: (height - 2)+'px'}">
      <slot>{{ name }}</slot>
    </router-link>
    <a
      v-else
      @click.stop="$emit('click')"
      :disabled="disabled"
      class="u-button"
      :class="[type, size, {[effect]: type === 'default', widthType: width, disabled: disabled}]"
      :style="{borderRadius: borderRadius + 'px', width: (width - 2) + 'px', height: (height - 2)+'px', lineHeight: (height - 2)+'px'}">
      <slot>{{ name }}</slot>
    </a>
  </span>
</template>
<style lang="less" scoped>
@primary: '#1890FF';
@danger: '#ff4d4f';
.m-button {
  display: inline-block;
  .u-button {
    display: inline-block;
    color: rgba(0,0,0,.65);
    background-color: #fff;
    border: 1px solid #d9d9d9;
    box-shadow: 0 2px 0 rgb(0 0 0 / 2%);
    transition: all .3s cubic-bezier(.645,.045,.355,1);
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    cursor: pointer;
  }
  .primary {
    color: #fff;
    background-color: @primary;
    border-color: @primary;
    text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
    box-shadow: 0 2px 0 rgb(0 0 0 / 5%);
    &:hover {
      background-color: #40a9ff;
      border-color: #40a9ff;
    }
    &:active {
      background-color: #096dd9;
      border-color: #096dd9;
    }
  }
  .default {
    .fade();
  }
  .danger {
    color: #fff;
    background-color: @danger;
    border-color: @danger;
    text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
    box-shadow: 0 2px 0 rgb(0 0 0 / 5%);
    &:hover {
      background-color: #ff7875;
      border-color: #ff7875;
    }
    &:active {
      background-color: #d9363e;
      border-color: #d9363e;
    }
  }
  .fade {
    &:hover {
      color: #40a9ff;
      border-color: #40a9ff;
    }
    &:active {
      color: #096dd9;
      border-color: #096dd9;
    }
  }
  .reverse {
    &:hover {
      color: #fff;
      background-color: #40a9ff;
      border-color: #40a9ff;
    }
    &:active {
      color: #fff;
      background-color: #096dd9;
      border-color: #096dd9;
    }
  }
  .small {
    height: 24px;
    line-height: 24px;
    padding: 0 7px;
    font-size: 14px;
  }
  .middle {
    height: 32px;
    line-height: 32px;
    padding: 0 15px;
    font-size: 14px;
  }
  .large {
    height: 40px;
    line-height: 40px;
    padding: 0 15px;
    font-size: 16px;
  }
  .widthType {
    padding: 0;
    text-align: center;
  }
  .disabled {
    color: rgba(0, 0, 0, 0.25);
    background-color: #f5f5f5;
    border-color: #d9d9d9;
    text-shadow: none;
    box-shadow: none;
  }
}
.center {
  display: block;
  text-align: center;
}
</style>

②在要使用的页面引入:

<script setup lang="ts">
import Button from './Button.vue'
function onClick () {
  console.log('click')
}
</script>
<template>
  <Button
    class="mr20"
    type="primary"
    effect="reverse"
    size="middle"
    :width="120"
    :height="40"
    :borderRadius="4"
    :disabled="false"
    :center="false"
    @click="onClick">
    按钮Button
  </Button>
</template>

http://www.niftyadmin.cn/n/139349.html

相关文章

java多线程与线程池-03线程池与阻塞队列

第6章 线程池与阻塞队列 6.1 Queue接口 队列是一种特殊的集合,一般队列都具有先进先出(FIFO)的特性(并不绝对要求)。优先级队列(PriorityQueue)按照元素的比较方法排序,其他队列基本采用自然序排队。 队列Queue接口实现了Collection接口,offer()方法负责把元素插入…

Linux 安装 nginx 详细教程

文章目录Linux 安装 nginx 详细步骤①安装依赖包②下载并解压安装包③安装 nginx④启动 nginx 服务⑤配置 nginx.conf提示&#xff1a;以下是本篇文章正文内容&#xff0c;Linux 系列学习将会持续更新 Linux 安装 nginx 详细步骤 ①安装依赖包 下载模块依赖性 Nginx 需要依赖…

【并发基础】操作系统中线程/进程的生命周期与状态流转以及Java线程的状态流转详解

目录 一、操作系统中进程和线程的状态 1.1 进程 1.1.1 进程的概念 1.1.2 进程的状态 1.1.3 进程调度流程图&#xff08;五状态&#xff09; 1.1.4 挂起状态 1.1.4 进程调度流程图&#xff08;六状态和七状态&#xff09; 1.1.5 睡眠状态 1.1.6 进程的诞生与消亡 1.2 线程 1.2.1…

Reactor响应式流的核心机制——背压机制

响应式流是什么&#xff1f; 响应式流旨在为无阻塞异步流处理提供一个标准。它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者&#xff0c;而不需要发布者阻塞&#xff0c;或订阅者有无限制的缓冲区或丢弃。 响应式流模型存在两种基本的实现机制。一种就是传统…

项目实战典型案例24——xxljob控制台不打印日志排查

xxljob控制台不打印日志排查一&#xff1a;背景介绍问题截图问题解读二&#xff1a;思路&方案三&#xff1a;过程四&#xff1a;总结一&#xff1a;背景介绍 本篇博客是对xxljob控制台不打印日志排查进行的总结和进行的改进。 目的是将经历转变为自己的经验。通过博客的方…

Java面试题--SpringMVC的执行流程

概要 SpringMVC是一种基于MVC&#xff08;Model-View-Controller&#xff09;框架的Web应用开发框架。下面是SpringMVC的详细执行流程。 客户端向DispatcherServlet发送请求。DispatcherServlet收到请求后&#xff0c;根据HandlerMapping&#xff08;处理器映射&#xff09;找…

常见的点云下载地址/点云集合/点云库

1、Princeton ModelNet https://modelnet.cs.princeton.edu/ 2、pcl的一些数据 https://sourceforge.net/projects/pointclouds/files/PCD%20datasets/

66 - 进程互斥锁的应用示例

---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;深入浅出操作系统 - 目录 文章目录1. 简单生产消费者问题1.1 具体问题描述1.2 解决方案1.3 简单生产消费者问题模型1.4 编程实验&#xff1a;生产消费者示例2. 多任务读写问题&a…