File size: 1,453 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
<template>
<span
class="switch"
:class="{
'active': value,
'disabled': disabled,
}"
@click="handleChange()"
>
<span class="switch-core"></span>
</span>
</template>
<script lang="ts" setup>
const props = withDefaults(defineProps<{
value: boolean
disabled?: boolean
}>(), {
disabled: false,
})
const emit = defineEmits<{
(event: 'update:value', payload: boolean): void
}>()
const handleChange = () => {
if (props.disabled) return
emit('update:value', !props.value)
}
</script>
<style lang="scss" scoped>
.switch {
height: 20px;
display: inline-block;
cursor: pointer;
&:not(.disabled).active {
.switch-core {
border-color: $themeColor;
background-color: $themeColor;
&::after {
left: 100%;
margin-left: -17px;
}
}
}
&.disabled {
cursor: default;
.switch-core::after {
background-color: #f5f5f5;
}
}
}
.switch-core {
margin: 0;
display: inline-block;
position: relative;
width: 40px;
height: 20px;
border: 1px solid #d9d9d9;
outline: none;
border-radius: 10px;
box-sizing: border-box;
background: #d9d9d9;
transition: border-color .3s, background-color .3s;
vertical-align: middle;
&::after {
content: '';
position: absolute;
top: 1px;
left: 1px;
border-radius: 100%;
transition: all .3s;
width: 16px;
height: 16px;
background-color: #fff;
}
}
</style> |