|
1 |
| -<script setup lang="ts"> |
2 |
| -const props = defineProps(['modelValue']) |
| 1 | +<script lang="ts" setup> |
| 2 | +import {computed, onMounted} from "vue"; |
| 3 | +// 定义 props 属性 |
| 4 | +const props = defineProps({ |
| 5 | + // 选中状态 |
| 6 | + modelValue: { |
| 7 | + type: Boolean, |
| 8 | + default: false |
| 9 | + }, |
| 10 | + // 尺寸大小 |
| 11 | + size: { |
| 12 | + type: Number, |
| 13 | + default: 24 |
| 14 | + }, |
| 15 | + // 打开时的背景色 |
| 16 | + activeColor: { |
| 17 | + type: String, |
| 18 | + default: '#1989fa' |
| 19 | + }, |
| 20 | + // 关闭时的背景色 |
| 21 | + inactiveColor: { |
| 22 | + type: String, |
| 23 | + default: '#cccccc' |
| 24 | + }, |
| 25 | + // 是否禁止切换 |
| 26 | + disabled: { |
| 27 | + type: Boolean, |
| 28 | + default: false |
| 29 | + } |
| 30 | +}) |
| 31 | +// 计算属性 |
| 32 | +const styleObj = computed(() => { |
| 33 | + return { |
| 34 | + fontSize: `${props.size}px`, |
| 35 | + backgroundColor: props.modelValue ? props.activeColor : props.inactiveColor |
| 36 | + } |
| 37 | +}) |
| 38 | +const styleObjCircle = computed(() => { |
| 39 | + return { |
| 40 | + width: `${props.size}px`, |
| 41 | + height: `${props.size}px` |
| 42 | + } |
| 43 | +}) |
| 44 | +const classObj = computed(() => { |
| 45 | + return { |
| 46 | + 'zw-switch-on': props.modelValue, |
| 47 | + 'zw-switch-disabled': props.disabled |
| 48 | + } |
| 49 | +}) |
| 50 | +
|
| 51 | +// 定义 emits |
3 | 52 | const emits = defineEmits(['update:modelValue'])
|
4 |
| -const onClick = ()=>{ |
5 |
| - emits('update:modelValue',!props.modelValue) |
| 53 | +
|
| 54 | +// 点击事件 |
| 55 | +const onClick = () => { |
| 56 | + if (props.disabled) return |
| 57 | + emits('update:modelValue', !props.modelValue) |
6 | 58 | }
|
| 59 | +
|
| 60 | +// 生命周期函数 |
| 61 | +onMounted(() => { |
| 62 | + console.log(123) |
| 63 | +}) |
| 64 | +
|
7 | 65 | </script>
|
8 | 66 |
|
9 | 67 | <template>
|
10 |
| - <div class="zw-switch" :class="props.modelValue?'zw-switch-on':''" @click="onClick"> |
11 |
| - <span class="node"></span> |
| 68 | + <div :class="classObj" :style="styleObj" class="zw-switch" @click="onClick"> |
| 69 | + <div :style="styleObjCircle" class="node"></div> |
12 | 70 | </div>
|
13 | 71 | </template>
|
14 | 72 |
|
15 | 73 | <style lang="scss" scoped>
|
16 | 74 | @import "style/var.scss";
|
17 | 75 |
|
18 | 76 | .zw-switch {
|
19 |
| - width: $switch-width; |
20 |
| - height: $switch-height; |
21 |
| - border: $switch-border-color; |
22 |
| - border-radius: $switch-border-radius; |
23 |
| - background-color: $switch-background-color; |
24 | 77 | position: relative;
|
| 78 | + display: inline-block; |
| 79 | + box-sizing: inherit; |
| 80 | + width: 2em; |
| 81 | + height: 1em; |
| 82 | + border-radius: 1em; |
| 83 | + font-size: 24px; |
| 84 | + border: $switch-border-color; |
| 85 | + padding: 1px; |
25 | 86 |
|
26 | 87 | .node {
|
27 |
| - width: 18px; |
28 |
| - height: 18px; |
| 88 | + width: 50px; |
| 89 | + height: 50px; |
29 | 90 | border: $switch-border-color;
|
30 | 91 | background-color: #fff;
|
31 | 92 | display: inline-block;
|
32 |
| - border-radius: 50%; |
| 93 | + border-radius: 100%; |
33 | 94 | position: absolute;
|
34 |
| - top: 2px; |
35 |
| - left: 2px; |
| 95 | + top: 1px; |
| 96 | + left: 1px; |
36 | 97 | transition: transform $switch-transition-duration cubic-bezier(0.3, 1.05, 0.4, 1.05);
|
37 | 98 | }
|
38 | 99 |
|
39 |
| - &-on{ |
40 |
| - background-color: #1989fa; |
41 |
| - box-shadow: 0 0 0 2px rgba(45,140,240,.2); |
| 100 | + &-on { |
| 101 | + box-shadow: 0 0 0 1px rgba(45, 140, 240, .1); |
42 | 102 |
|
43 |
| - .node{ |
44 |
| - transform: translateX($switch-width - 18px - 4px); |
| 103 | + .node { |
| 104 | + transform: translateX(100%); |
45 | 105 | }
|
46 | 106 | }
|
47 | 107 |
|
| 108 | + &-disabled { |
| 109 | + opacity: .5; |
| 110 | + cursor: not-allowed; |
| 111 | + } |
48 | 112 | }
|
49 | 113 | </style>
|
0 commit comments