Switch 开关
开关选择组件,支持自定义选中值、自定义文本、自定义颜色、禁用。
组件源码
vue
<script lang="ts" generic="T extends (string | number | boolean)" setup>
import { computed } from 'vue';
const $props = withDefaults(
defineProps<{
disabled?: boolean;
activeValue?: T;
inactiveValue?: T;
activeText?: string;
inactiveText?: string;
activeColor?: string;
activeBgColor?: string;
inactiveColor?: string;
inactiveBgColor?: string;
textColor?: string;
}>(),
{
disabled: false,
activeText: 'YES',
inactiveText: 'NO',
activeColor: '#03a9f4',
activeBgColor: '#ebf7fc',
inactiveColor: '#f44336',
inactiveBgColor: '#fcebeb',
textColor: '#fff'
}
);
const checked = defineModel<T>('checked', { default: false as T });
const nativeChecked = computed({
get: () => {
if ($props.activeValue) {
return checked.value === $props.activeValue;
}
if ($props.inactiveValue) {
return checked.value !== $props.inactiveValue;
}
return !!checked.value;
},
set: (value: boolean) => {
if ($props.disabled) return;
if (value) {
checked.value = $props.activeValue ?? (true as T);
return;
}
checked.value = $props.inactiveValue ?? (false as T);
}
});
</script>
<template>
<div class="base-switch-button">
<input
class="base-switch-checkbox"
type="checkbox"
v-model="nativeChecked" />
<div
class="knobs"
:class="disabled ? 'knobs--disabled' : ''"
:data-text="nativeChecked ? activeText : inactiveText"></div>
<div class="layer"></div>
</div>
</template>
<style lang="scss" scoped>
.base-switch-button {
overflow: hidden;
position: relative;
width: 74px;
height: 36px;
border-radius: 18px;
color: v-bind(textColor);
.base-switch-checkbox {
position: relative;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
opacity: 0;
cursor: pointer;
z-index: 3;
}
.knobs:before {
content: attr(data-text);
position: absolute;
top: 50%;
left: 6px;
transform: translateY(-50%);
padding: 5px 2px;
width: 24px;
height: 24px;
font-size: 10px;
text-align: center;
line-height: 14px;
background-color: v-bind(inactiveColor);
border-radius: 15px;
transition: 0.3s ease all, left 0.3s cubic-bezier(0.18, 0.89, 0.35, 1.15);
}
.base-switch-checkbox:checked + .knobs:before {
content: attr(data-text);
left: 44px;
background-color: v-bind(activeColor);
}
.base-switch-checkbox:checked ~ .layer {
background-color: v-bind(activeBgColor);
}
}
.knobs,
.layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.knobs {
z-index: 2;
}
.knobs--disabled {
z-index: 4;
cursor: not-allowed;
}
.layer {
width: 100%;
background-color: v-bind(inactiveBgColor);
transition: 0.3s ease all;
z-index: 1;
}
</style>基本用法
示例代码
vue
<template>
<div class="container">
<div class="flex">
<label for="" class="mr-10">简单使用:</label>
<base-switch v-model:checked="checked1" />
</div>
<div class="flex">
<label for="" class="mr-10">指定值:</label>
<base-switch
:active-value="1"
:inactive-value="0"
v-model:checked="checked2" />
</div>
<div class="flex">
<label for="" class="mr-10">自定义文本:</label>
<base-switch active-text="开" inactive-text="关" />
</div>
<div class="flex">
<label for="" class="mr-10">自定义颜色:</label>
<base-switch
text-color="#000"
active-color="#67C23A"
active-bg-color="#f0f9eb"
inactive-color="#fff"
inactive-bg-color="#999" />
</div>
</div>
</template>
<script lang="ts" setup>
import BaseSwitch from '@/BaseSwitch/BaseSwitch.vue';
import { ref } from 'vue';
const checked1 = ref(false);
const checked2 = ref(1);
</script>
<style lang="scss" scoped>
.container {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
}
.flex {
display: flex;
align-items: center;
}
.mr-10 {
margin-right: 10px;
}
</style>API
Props
| 参数名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| checked(v-model) | 绑定值 | boolean | number | string | false |
| activeValue | 选中值 | boolean | number | string | - |
| inactiveValue | 未选中值 | boolean | number | string | - |
| activeText | 选中文本 | string | YES |
| inactiveText | 未选中文本 | string | NO |
| activeColor | 选中颜色 | string | #03a9f4 |
| activeBgColor | 选中背景颜色 | string | #ebf7fc |
| inactiveColor | 未选中颜色 | string | #f44336 |
| inactiveBgColor | 未选中背景颜色 | string | #fcebeb |
| disabled | 是否禁用 | boolean | false |
| textColor | 文本颜色 | string | #fff |
Events
| 事件名 | 说明 | 参数 |
|---|---|---|
| update:checked | 开关状态切换时触发 | checked: boolean | number | string |