拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Vue3按钮(Button)

可自定义设置以下属性设置按钮类型type类型default | reverse | primary | danger | dashed | text | link默认 default设置按钮形状shape类型default | circle | round默认 default设置按钮图标icon类型VNode | Slot默认 undefined设置按钮尺寸size类型small | middle | large默认 middle按钮背景是否透明ghost类型boolean仅当 type: primary | danger 时生效默认 false设置按钮类名buttonClass类型string默认 undefined按钮颜色color类型string默认 undefined点击跳转的地址href与 a 链接的 href 属性一致类型string默认 undefined如何打开目标链接target相当于 a 链接的 target 属性href 存在时生效类型_self | _blank默认 _self是否支持键盘操作keyboard类型boolean默认 true是否禁用disabled类型boolean默认 false是否加载中loading类型boolean默认 false加载指示符类型loadingType类型static | dynamic默认 dynamic是否将按钮宽度调整为其父宽度block类型boolean默认 false效果如下图在线预览①创建按钮组件Button.vue其中引入使用了以下工具函数监听插槽存在 useSlotsExist获取依赖注入 useInjectscript setup langts import { ref, nextTick, computed } from vue import type { VNode, Slot } from vue import { generate } from ant-design/colors import { useSlotsExist, useInject } from components/utils export interface Props { type?: default | reverse | primary | danger | dashed | text | link // 设置按钮类型 shape?: default | circle | round // 设置按钮形状 icon?: VNode | Slot // 设置按钮图标 size?: small | middle | large // 设置按钮尺寸 ghost?: boolean // 按钮背景是否透明仅当 type: primary | danger 时生效 buttonClass?: string // 设置按钮类名 color?: string // 按钮颜色 href?: string // 点击跳转的地址与 a 链接的 href 属性一致 target?: _self | _blank // 如何打开目标链接相当于 a 链接的 target 属性href 存在时生效 keyboard?: boolean // 是否支持键盘操作 disabled?: boolean // 是否禁用 loading?: boolean // 是否加载中 loadingType?: static | dynamic // 加载指示符类型 block?: boolean // 是否将按钮宽度调整为其父宽度 } const props withDefaults(definePropsProps(), { type: default, shape: default, icon: undefined, size: middle, ghost: false, color: undefined, buttonClass: undefined, href: undefined, target: _self, keyboard: true, disabled: false, loading: false, loadingType: dynamic, block: false }) const wave refboolean(false) const { colorPalettes } useInject(Button) // 主题色注入 const colorPalettesComputed computed(() { if (props.color ! undefined) { return generate(props.color) } return colorPalettes.value }) const rippleColorComputed computed(() { const presetRippleColors { default: colorPalettesComputed.value[5], reverse: colorPalettesComputed.value[5], primary: colorPalettesComputed.value[5], danger: #ff4d4f, dashed: colorPalettesComputed.value[5], text: transparent, link: transparent } return presetRippleColors[props.type] }) const emit defineEmits([click]) const slotsExist useSlotsExist([icon, default]) const showIcon computed(() { return slotsExist.icon || props.icon }) const showIconOnly computed(() { return showIcon.value !slotsExist.default }) function onClick(e: Event) { if (wave.value) { wave.value false nextTick(() { wave.value true }) } else { wave.value true } emit(click, e) } function onKeyboard(e: KeyboardEvent) { onClick(e) } function onWaveEnd() { wave.value false } /script template component :ishref ? a : div tabindex0 classbtn-wrap :class[ btn-${type} btn-${size}, { [loading-${size}]: !href loading, btn-icon-only: showIconOnly, btn-circle: shape circle, btn-round: shape round, btn-loading-blur: !href loading, btn-ghost: ghost, btn-block: block, btn-disabled: disabled }, buttonClass ] :style --button-primary-color: ${colorPalettesComputed[5]}; --button-primary-color-hover: ${colorPalettesComputed[4]}; --button-primary-color-active: ${colorPalettesComputed[6]}; --button-danger-color: #ff4d4f; --button-danger-color-hover: #ff7875; --button-danger-color-active: #d9363e; --button-text-color-hover: rgba(0, 0, 0, 0.06); --button-text-color-active: rgba(0, 0, 0, 0.15); --button-ripple-color: ${rippleColorComputed}; :hrefhref :targettarget clickdisabled || loading ? () false : onClick($event) keydown.enter.preventkeyboard !disabled !loading ? onKeyboard($event) : () false div v-ifloading || !showIcon classbtn-loading div v-if!href loadingType static classstatic-circle svg classcircle width1em height1em fillcurrentColor viewBox0 0 100 100 path dM 50,50 m 0,-45 a 45,45 0 1 1 0,90 a 45,45 0 1 1 0,-90 stroke-linecapround classpath fill-opacity0 /path /svg /div div v-if!href loadingType dynamic classdynamic-circle svg classcircle viewBox0 0 50 50 width1em height1em fillcurrentColor circle classpath cx25 cy25 r20 fillnone/circle /svg /div /div span v-if!loading showIcon classbtn-icon slot nameicon component v-ificon :isicon / /slot /span span v-ifslotsExist.default classbtn-content slot/slot /span div v-if!disabled classbutton-wave :class{ wave-active: wave } animationendonWaveEnd/div /component /template style langless scoped .btn-wrap { position: relative; display: inline-flex; align-items: center; justify-content: center; font-weight: 400; line-height: 1.5714285714285714; color: rgba(0, 0, 0, 0.88); white-space: nowrap; text-align: center; background-color: transparent; border: 1px solid transparent; outline: none; user-select: none; text-decoration: none; cursor: pointer; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); .btn-loading { display: inline-flex; align-items: center; overflow: hidden; opacity: 0; width: 0; transition: margin-right 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), opacity 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); .static-circle, .dynamic-circle { display: inline-flex; justify-content: start; .circle .path { stroke: currentColor; } } .static-circle { .circle { animation: spinCircle 0.8s linear infinite; -webkit-animation: spinCircle 0.8s linear infinite; .path { stroke-width: 10; stroke-dashoffset: 0; stroke-dasharray: 84.82px, 282.74px; } } } .dynamic-circle { .circle { animation: spinCircle 2s linear infinite; -webkit-animation: spinCircle 2s linear infinite; .path { stroke-width: 5; stroke-dasharray: 90, 150; stroke-dashoffset: 0; stroke-linecap: round; animation: loadingDash 1.5s ease-in-out infinite; -webkit-animation: loadingDash 1.5s ease-in-out infinite; keyframes loadingDash { 0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -40px; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124px; } } } } } keyframes spinCircle { 100% { transform: rotate(360deg); } } } .btn-icon, .btn-content { display: inline-flex; align-items: center; :deep(svg) { fill: currentColor; } } .button-wave { position: absolute; pointer-events: none; top: 0; right: 0; bottom: 0; left: 0; animation-iteration-count: 1; animation-duration: 0.6s; animation-timing-function: cubic-bezier(0, 0, 0.2, 1), cubic-bezier(0, 0, 0.2, 1); border-radius: inherit; } .wave-active { z-index: 1; animation-name: waveSpread, waveOpacity; keyframes waveSpread { from { box-shadow: 0 0 0.5px 0 var(--button-ripple-color); } to { box-shadow: 0 0 0.5px 5.5px var(--button-ripple-color); } } keyframes waveOpacity { from { opacity: 0.6; } to { opacity: 0; } } } .btn-icon .btn-content { margin-left: 8px; } } .btn-default { background-color: #ffffff; border-color: #d9d9d9; :hover { color: var(--button-primary-color-hover) !important; border-color: var(--button-primary-color-hover); } :active { color: var(--button-primary-color-active) !important; border-color: var(--button-primary-color-active); } .btn-icon { :deep(svg) { transition: fill 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); } } } .btn-reverse { .btn-default(); :hover { color: #fff !important; background-color: var(--button-primary-color); border-color: var(--button-primary-color); } :active { color: #fff !important; background-color: var(--button-primary-color-active); border-color: var(--button-primary-color-active); } } .btn-primary { color: #fff; background-color: var(--button-primary-color); border-color: var(--button-primary-color); :hover { color: #fff; background-color: var(--button-primary-color-hover); border-color: var(--button-primary-color-hover); } :active { color: #fff; background-color: var(--button-primary-color-active); border-color: var(--button-primary-color-active); } } .btn-danger { color: #fff; background-color: var(--button-danger-color); border-color: var(--button-danger-color); :hover { color: #fff; background-color: var(--button-danger-color-hover); border-color: var(--button-danger-color-hover); } :active { color: #fff; background-color: var(--button-danger-color-active); border-color: var(--button-danger-color-active); } } .btn-dashed { .btn-default(); border-style: dashed; } .btn-text { :hover { background-color: var(--button-text-color-hover); } :active { background-color: var(--button-text-color-active); } } .btn-link { color: var(--button-primary-color); :hover { color: var(--button-primary-color-hover); } :active { color: var(--button-primary-color-active); } .btn-icon { :deep(svg) { transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); } } } .btn-small { font-size: 14px; height: 24px; padding: 0 7px; border-radius: 4px; } .btn-middle { font-size: 14px; height: 32px; padding: 4px 15px; border-radius: 6px; } .btn-large { font-size: 16px; height: 40px; padding: 6.428571428571429px 15px; border-radius: 8px; } .loading-small, .loading-middle { .btn-loading { margin-right: 8px; width: 1em; opacity: 1; } } .loading-large { .btn-loading { margin-right: 8px; width: 1em; opacity: 1; } } .btn-icon-only { width: 32px; padding-left: 0; padding-right: 0; .btn-loading, .btn-icon { transform: scale(1.143); } .btn-loading { margin-right: 0; } } .btn-small.btn-icon-only { width: 24px; padding-left: 0; padding-right: 0; } .btn-large.btn-icon-only { width: 40px; padding-left: 0; padding-right: 0; } .btn-circle { min-width: 32px; padding-left: 0; padding-right: 0; border-radius: 50%; } .btn-small.btn-circle { min-width: 24px; padding-left: 0; padding-left: 0; border-radius: 50%; } .btn-large.btn-circle { min-width: 40px; padding-left: 0; padding-right: 0; border-radius: 50%; } .btn-round { border-radius: 32px; padding-left: 16px; padding-right: 16px; } .btn-small.btn-round { border-radius: 24px; padding-left: 12px; padding-right: 12px; } .btn-large.btn-round { border-radius: 40px; padding-left: 20px; padding-right: 20px; } .btn-icon-only.btn-round, .btn-small.btn-icon-only.btn-round, .btn-large.btn-icon-only.btn-round { width: auto; } .btn-loading-blur { opacity: 0.65; pointer-events: none; } .btn-primary.btn-ghost:not(.btn-disabled) { color: var(--button-primary-color); border-color: var(--button-primary-color); background-color: transparent; :hover { color: var(--button-primary-color-hover); border-color: var(--button-primary-color-hover); } :active { color: var(--button-primary-color-active); border-color: var(--button-primary-color-active); } .btn-icon { :deep(svg) { transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); } } } .btn-danger.btn-ghost:not(.btn-disabled) { color: var(--button-danger-color); border-color: var(--button-danger-color); background-color: transparent; :hover { color: var(--button-danger-color-hover); border-color: var(--button-danger-color-hover); } :active { color: var(--button-danger-color-active); border-color: var(--button-danger-color-active); } .btn-icon { :deep(svg) { transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); } } } .btn-block { width: 100%; } .btn-disabled { color: rgba(0, 0, 0, 0.25); cursor: not-allowed; :not(.btn-text, .btn-link) { border-color: #d9d9d9; background-color: rgba(0, 0, 0, 0.04); } :not(.btn-text, .btn-link):hover, :not(.btn-text, .btn-link):active { border-color: #d9d9d9; color: rgba(0, 0, 0, 0.25) !important; background-color: rgba(0, 0, 0, 0.04); } .btn-text:hover, .btn-text:active { background-color: transparent; } .btn-link:hover, .btn-link:active { color: rgba(0, 0, 0, 0.25); } } /style②在要使用的页面引入其中引入使用了以下组件Vue3间距SpaceVue3文字提示TooltipVue3开关SwitchVue3单选框Radioscript setup langts import Button from ./Button.vue import { ref } from vue import { SearchOutlined, DownloadOutlined, CrownOutlined } from ant-design/icons-vue const disabled ref(true) const sizeOptions [ { label: small, value: small }, { label: middle, value: middle }, { label: large, value: large } ] const size ref(middle) const customLoading ref(false) const loading ref(true) const loadingOptions [ { label: static, value: static }, { label: dynamic, value: dynamic } ] const loadingType ref(dynamic) function onClick(e: Event) { console.log(click, e) } /script template div h1{{ $route.name }} {{ $route.meta.title }}/h1 h2 classmt30 mb10按钮类型/h2 Space Button clickonClickDefault Button/Button Button typereverseReverse Button/Button Button typeprimaryPrimary Button/Button Button typedangerDanger Button/Button Button typedashedDashed Button/Button Button typetextText Button/Button Button typelinkLink Button/Button /Space h2 classmt30 mb10按钮形状 图标/h2 Space vertical Space Tooltip tooltipsearch Button typeprimary shapecircle :iconSearchOutlined / /Tooltip Button typeprimary shapecircleA/Button Button typeprimary shaperound :iconSearchOutlined Search /Button Tooltip tooltipsearch Button typeprimary shaperound :iconSearchOutlined / /Tooltip Button typeprimary :iconSearchOutlined Search /Button /Space Space Tooltip tooltipsearch Button hrefhttps://themusecatcher.blog.csdn.net target_blank template #icon SearchOutlined / /template /Button /Tooltip Tooltip tooltipsearch Button shapecircle template #icon SearchOutlined / /template /Button /Tooltip Button template #icon SearchOutlined / /template Search /Button Tooltip tooltipsearch Button shaperound template #icon SearchOutlined / /template /Button /Tooltip Tooltip tooltipsearch Button typedashed shapecircle template #icon SearchOutlined / /template /Button /Tooltip Button typedashed template #icon SearchOutlined / /template Search /Button /Space Space Tooltip tooltipdownload Button typeprimary template #icon DownloadOutlined / /template /Button /Tooltip Tooltip tooltipdownload Button typeprimary shapecircle template #icon DownloadOutlined / /template /Button /Tooltip Button typeprimary shaperound template #icon DownloadOutlined / /template Download /Button Tooltip tooltipdownload Button typeprimary shaperound template #icon DownloadOutlined / /template /Button /Tooltip Button typeprimary template #icon DownloadOutlined / /template Download /Button /Space /Space h2 classmt30 mb10幽灵按钮/h2 Space Button typeprimary ghostPrimary Ghost Button/Button Button typedanger ghostDanger Ghost Button/Button Button typeprimary ghost shapecircle template #icon SearchOutlined / /template /Button Button typeprimary ghost shaperound template #icon SearchOutlined / /template Search /Button Button typeprimary ghost shaperound template #icon SearchOutlined / /template /Button Button typedanger ghost shapecircle template #icon DownloadOutlined / /template /Button Button typedanger ghost shaperound template #icon DownloadOutlined / /template Download /Button Button typedanger ghost shaperound template #icon DownloadOutlined / /template /Button /Space h2 classmt30 mb10禁用/h2 Space vertical Space aligncenter Disabled state:Switch v-modeldisabled / /Space Space Button :disableddisabledDefault Button/Button Button :disableddisabled typereverseReverse Button/Button Button :disableddisabled typeprimaryPrimary Button/Button Button :disableddisabled typedangerDanger Button/Button Button :disableddisabled typedashedDashed Button/Button Button :disableddisabled typetextText Button/Button Button :disableddisabled typelinkLink Button/Button /Space Space Button :disableddisabled typeprimary ghostPrimary Ghost Button/Button Button :disableddisabled typedanger ghostDanger Ghost Button/Button Button :disableddisabled typeprimary shapecircle template #icon SearchOutlined / /template /Button Button :disableddisabled typeprimary shaperound template #icon SearchOutlined / /template Search /Button Button :disableddisabled typeprimary shaperound template #icon SearchOutlined / /template /Button Button :disableddisabled typedanger shapecircle template #icon DownloadOutlined / /template /Button Button :disableddisabled typedanger shaperound template #icon DownloadOutlined / /template Download /Button Button :disableddisabled typedanger shaperound template #icon DownloadOutlined / /template /Button /Space /Space h2 classmt30 mb10按钮尺寸/h2 Space vertical Radio :optionssizeOptions v-model:valuesize button button-stylesolid / Space Button :sizesizeDefault Button/Button Button :sizesize typereverseReverse Button/Button Button :sizesize typeprimaryPrimary Button/Button Button :sizesize typedangerDanger Button/Button /Space Space Button :sizesize typedashedDashed Button/Button Button :sizesize typetextText Button/Button Button :sizesize typelinkLink Button/Button /Space Space Button :sizesize typeprimary ghostPrimary Button/Button Button :sizesize typedanger ghostDanger Button/Button Button :sizesize typeprimary ghost loadingPrimary Ghost Button/Button Button :sizesize typedanger ghost loadingDanger Ghost Button/Button /Space Space Button :sizesize typeprimary ghost template #icon SearchOutlined / /template /Button Button :sizesize typeprimary ghost shapecircle template #icon SearchOutlined / /template /Button Button :sizesize typeprimary ghost shaperound template #icon SearchOutlined / /template Search /Button Button :sizesize typeprimary ghost shaperound template #icon SearchOutlined / /template /Button Button :sizesize typeprimary ghost template #icon SearchOutlined / /template Search /Button /Space Space Button :sizesize typedanger template #icon DownloadOutlined / /template /Button Button :sizesize typedanger shapecircle template #icon DownloadOutlined / /template /Button Button :sizesize typedanger shaperound template #icon DownloadOutlined / /template Download /Button Button :sizesize typedanger shaperound template #icon DownloadOutlined / /template /Button Button :sizesize typedanger template #icon DownloadOutlined / /template Download /Button /Space /Space h2 classmt30 mb10自定义颜色/h2 Space vertical Space aligncenter Loading state:Switch v-modelcustomLoading / /Space Space Button typereverse color#d4380d :loadingcustomLoading template #icon CrownOutlined / /template #d4380d /Button Button typeprimary color#faad14 :loadingcustomLoading template #icon CrownOutlined / /template #faad14 /Button Button ghost typeprimary color#ff6900 :loadingcustomLoading template #icon CrownOutlined / /template #ff6900 /Button Button typeprimary shaperound color#18a058 :loadingcustomLoading template #icon CrownOutlined / /template #18a058 /Button /Space /Space h2 classmt30 mb10自定义跳转/h2 Space Button typeprimary ghost hrefhttps://themusecatcher.github.io/vue-amazing-ui/ target_blank template #icon img stylewidth: 1em; height: 1em srchttps://themusecatcher.github.io/vue-amazing-ui/amazing-logo.svg / /template Vue Amazing UI /Button Button typeprimary hrefhttps://themusecatcher.github.io/vue-amazing-ui/guide/components/button.html target_blank Button Component /Button Button typeprimary ghost shaperound hrefhttps://themusecatcher.blog.csdn.net target_blank My CSDN Blogs /Button /Space h2 classmt30 mb10加载中状态/h2 Space vertical Space aligncenter Loading state:Switch v-modelloading / /Space Space aligncenter Loading type:Radio :optionsloadingOptions v-model:valueloadingType / /Space Space Button :loadingloading :loading-typeloadingTypeDefault Button/Button Button typereverse :loadingloading :loading-typeloadingTypeReverse Button/Button Button typeprimary :loadingloading :loading-typeloadingTypePrimary Button/Button Button typedanger :loadingloading :loading-typeloadingTypeDanger Button/Button /Space Space Button typedashed :loadingloading :loading-typeloadingTypeDashed Button/Button Button typetext :loadingloading :loading-typeloadingTypeText Button/Button Button typelink :loadingloading :loading-typeloadingTypeLink Button/Button /Space Space Button typeprimary ghost :loadingloading :loading-typeloadingTypePrimary Ghost Button/Button Button typedanger ghost :loadingloading :loading-typeloadingTypeDanger Ghost Button/Button /Space Space Button typeprimary :loadingloading :loading-typeloadingType template #icon SearchOutlined / /template /Button Button typeprimary shapecircle :loadingloading :loading-typeloadingType template #icon SearchOutlined / /template /Button Button typeprimary shaperound :loadingloading :loading-typeloadingType template #icon SearchOutlined / /template Search /Button Button typeprimary shaperound :loadingloading :loading-typeloadingType template #icon SearchOutlined / /template /Button Button typedanger ghost :loadingloading :loading-typeloadingType template #icon DownloadOutlined / /template /Button Button typedanger ghost shapecircle :loadingloading :loading-typeloadingType template #icon DownloadOutlined / /template /Button Button typedanger ghost shaperound :loadingloading :loading-typeloadingType template #icon DownloadOutlined / /template Download /Button Button typedanger ghost shaperound :loadingloading :loading-typeloadingType template #icon DownloadOutlined / /template /Button /Space /Space h2 classmt30 mb10block 按钮/h2 Space Button blockDefault Button/Button Button block typeprimary shaperoundPrimary Button/Button Button block typedanger shaperoundDanger Button/Button Button block typeprimary ghostPrimary Button/Button Button block typedanger ghostDanger Button/Button /Space /div /template
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门