js
<component
:is="tag"
ref="_ref"
v-bind="_props"
:class="buttonKls"
:style="buttonStyle"
@click="handleClick"
>
:style="buttonStyle":用于在设置了 color 时,自动计算并应用按钮各状态(默认、悬停、激活、禁用)的颜色样式,无需手动设置每个状态的颜色。
js
const buttonStyle = useButtonCustomStyle(props)
/**
* 获取实例中props为name的值
*/
export const useProp = <T>(name: string): ComputedRef<T | undefined> => {
const vm = getCurrentInstance()
return computed(() => (vm?.proxy?.$props as any)?.[name])
}
/**
* 获取表单的disabled状态
* @param fallback 默认值
* @returns 表单的disabled状态
*/
export const useFormDisabled = (fallback?: MaybeRef<boolean | undefined>) => {
const disabled = useProp<boolean>('disabled')
const form = inject(formContextKey, undefined)
// 如果是表单内部的button那么是有值的,如果是外部的button那么是undefined
console.log('form', form)
/**
* 组件自身的 disabled prop
↓ (如果没有)
传入的 fallback 参数
↓ (如果没有)
表单的 disabled 状态
↓ (如果没有)
默认值 false
*/
return computed(
() => disabled.value || unref(fallback) || form?.disabled || false
)
}
/**
* 获取按钮自定义样式
* @param props
* @returns
*/
export function useButtonCustomStyle(props: ButtonProps) {
// 获取按钮的disabled状态
const _disabled = useFormDisabled()
// 获取按钮的命名空间
const ns = useNamespace('button')
// calculate hover & active color by custom color
// only work when custom color
return computed(() => {
let styles: Record<string, string> = {}
let buttonColor = props.color
if (buttonColor) {
// 检测buttonColor是否为CSS变量格式 ,并提取变量名 如 var(--el-color-primary)
const match = (buttonColor as string).match(/var\((.*?)\)/)
if (match) {
buttonColor = window
.getComputedStyle(window.document.documentElement)
.getPropertyValue(match[1])
}
// TinyColor: Fast, small color manipulation and conversion for JavaScript
const color = new TinyColor(buttonColor)
console.log('color', color)
// tint - 变亮(添加白色)变亮20%
// darken - 变暗(添加黑色)变暗20%
const activeBgColor = props.dark
? color.tint(20).toString()
: darken(color, 20)
if (props.plain) {
styles = ns.cssVarBlock({
'bg-color': props.dark
? darken(color, 90)
: color.tint(90).toString(),
'text-color': buttonColor,
'border-color': props.dark
? darken(color, 50)
: color.tint(50).toString(),
'hover-text-color': `var(${ns.cssVarName('color-white')})`,
'hover-bg-color': buttonColor,
'hover-border-color': buttonColor,
'active-bg-color': activeBgColor,
'active-text-color': `var(${ns.cssVarName('color-white')})`,
'active-border-color': activeBgColor,
})
if (_disabled.value) {
styles[ns.cssVarBlockName('disabled-bg-color')] = props.dark
? darken(color, 90)
: color.tint(90).toString()
styles[ns.cssVarBlockName('disabled-text-color')] = props.dark
? darken(color, 50)
: color.tint(50).toString()
styles[ns.cssVarBlockName('disabled-border-color')] = props.dark
? darken(color, 80)
: color.tint(80).toString()
}
} else {
const hoverBgColor = props.dark
? darken(color, 30)
: color.tint(30).toString()
const textColor = color.isDark()
? `var(${ns.cssVarName('color-white')})`
: `var(${ns.cssVarName('color-black')})`
styles = ns.cssVarBlock({
'bg-color': buttonColor,
'text-color': textColor,
'border-color': buttonColor,
'hover-bg-color': hoverBgColor,
'hover-text-color': textColor,
'hover-border-color': hoverBgColor,
'active-bg-color': activeBgColor,
'active-border-color': activeBgColor,
})
if (_disabled.value) {
const disabledButtonColor = props.dark
? darken(color, 50)
: color.tint(50).toString()
styles[ns.cssVarBlockName('disabled-bg-color')] = disabledButtonColor
styles[ns.cssVarBlockName('disabled-text-color')] = props.dark
? 'rgba(255, 255, 255, 0.5)'
: `var(${ns.cssVarName('color-white')})`
styles[ns.cssVarBlockName('disabled-border-color')] =
disabledButtonColor
}
}
}
return styles
})
}
==========================================
js
props:native-type
export const buttonNativeTypes = ['button', 'submit', 'reset'] as const
props:
/**
* @description native button type
*/
nativeType: {
type: String,
values: buttonNativeTypes,
default: 'button',
},