Skip to content

Commit 76b0b8f

Browse files
committed
switch组件支持 size,disabled,activeColor,inactiveColor
1 parent ed08fde commit 76b0b8f

File tree

6 files changed

+131
-59
lines changed

6 files changed

+131
-59
lines changed

src/App.vue

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
11
<script setup lang="ts">
2+
import HelloWorld from './components/HelloWorld.vue'
23
import DemoSwitch from './components/DemoSwitch.vue'
34
</script>
45

56
<template>
7+
<HelloWorld msg="jam" />
68
<DemoSwitch />
79
</template>
810

911
<style scoped>
10-
.logo {
11-
height: 6em;
12-
padding: 1.5em;
13-
will-change: filter;
14-
}
15-
.logo:hover {
16-
filter: drop-shadow(0 0 2em #646cffaa);
17-
}
18-
.logo.vue:hover {
19-
filter: drop-shadow(0 0 2em #42b883aa);
20-
}
2112
</style>

src/components/DemoSwitch.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<script setup lang="ts">
22
import Switch from "../lib/Switch.vue"
33
import {ref} from "vue";
4-
let status = ref(false)
4+
let status = ref(true)
5+
let size = ref(24)
56
</script>
67
<template>
7-
<Switch v-model="status" />
8+
<button @click="size++">尺寸+1</button>
9+
<button @click="size--">尺寸-1</button>
10+
<Switch v-model="status" :size="size" :disabled="false" />
811
</template>
912

1013
<style lang="scss" scoped>

src/components/HelloWorld.vue

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,47 @@
11
<script setup lang="ts">
2-
import { ref } from 'vue'
2+
import { ref, reactive, nextTick } from 'vue'
3+
const count = ref(0)
4+
const state = reactive({
5+
count:0,
6+
goods:{
7+
count:0
8+
},
9+
list:[1,2,3]
10+
})
311
412
defineProps<{ msg: string }>()
513
6-
const count = ref(0)
14+
const onAdd = ()=>{
15+
state.count++
16+
count.value++
17+
18+
// 深层响应式,以下操作也可以检测到,vue2不行
19+
state.goods.count++
20+
state.list.push(7)
21+
22+
nextTick(()=>{
23+
console.log('DOM 更新了')
24+
})
25+
}
26+
27+
728
</script>
829

930
<template>
1031
<h1>{{ msg }}</h1>
1132

1233
<div class="card">
13-
<button type="button" @click="count++">count is {{ count }}</button>
14-
<p>
15-
Edit
16-
<code>components/HelloWorld.vue</code> to test HMR
17-
</p>
34+
<button type="button" @click="onAdd">count is {{ count }}--{{state.count }}</button>
35+
</div>
36+
<div>
37+
goods: {{ state.goods.count }}
38+
</div>
39+
<div v-for="(item,index) in state.list" :key="index">
40+
<span>{{ item }}</span>
1841
</div>
1942

20-
<p>
21-
Check out
22-
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
23-
>create-vue</a
24-
>, the official Vue + Vite starter
25-
</p>
26-
<p>
27-
Install
28-
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
29-
in your IDE for a better DX
30-
</p>
31-
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
3243
</template>
3344

3445
<style scoped>
35-
.read-the-docs {
36-
color: #888;
37-
}
46+
3847
</style>

src/lib/Switch.vue

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,113 @@
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
352
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)
658
}
59+
60+
// 生命周期函数
61+
onMounted(() => {
62+
console.log(123)
63+
})
64+
765
</script>
866

967
<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>
1270
</div>
1371
</template>
1472

1573
<style lang="scss" scoped>
1674
@import "style/var.scss";
1775
1876
.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;
2477
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;
2586
2687
.node {
27-
width: 18px;
28-
height: 18px;
88+
width: 50px;
89+
height: 50px;
2990
border: $switch-border-color;
3091
background-color: #fff;
3192
display: inline-block;
32-
border-radius: 50%;
93+
border-radius: 100%;
3394
position: absolute;
34-
top: 2px;
35-
left: 2px;
95+
top: 1px;
96+
left: 1px;
3697
transition: transform $switch-transition-duration cubic-bezier(0.3, 1.05, 0.4, 1.05);
3798
}
3899
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);
42102
43-
.node{
44-
transform: translateX($switch-width - 18px - 4px);
103+
.node {
104+
transform: translateX(100%);
45105
}
46106
}
47107
108+
&-disabled {
109+
opacity: .5;
110+
cursor: not-allowed;
111+
}
48112
}
49113
</style>

src/lib/style/var.scss

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
$animation-duration-base: 0.3s;
33

44
// Switch
5-
$switch-width: 44px;
6-
$switch-height: 22px;
7-
$switch-border-radius: 11px;
85
$switch-border-color: #ccc;
96
$switch-background-color: #ccc;
107
$switch-transition-duration: $animation-duration-base;

src/lib/utils/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// 添加单位
2+
export const addUnit = (value="auto", unit="px") => {
3+
if(typeof(value)=='string'){
4+
return value
5+
}else if(typeof(value)=='number'){
6+
return `${value}${unit}`
7+
}
8+
}

0 commit comments

Comments
 (0)