效果

API设计
<Switch value="true" /> value 为字符串 "true"
<Switch value="false" /> value 为字符串 "false"
或者
<Switch :value=" true " /> value 为布尔值 true
<Switch :value=" false " /> value 为布尔值 false
note:
- 当 value 为字符串 "true" 或布尔值 true 时,显示为开
- 其他情况一律显示为关
悬浮切换动画
<template>
<div>
<!-- @input表示变化的时候让y为最新的值, 最新的值就是$event-->
<Switch :value="y" @input="y = $event"></Switch>
</div>
</template>
<script lang="ts">
import Switch from "../lib/Switch.vue";
import { ref } from "vue";
export default {
components: { Switch },
setup() {
const y = ref(false);
return { y };
// 给value 默认值y ,y为true ,
},
};
</script>
<style lang="scss" scoped>
$h: 22px;
$h2: $h - 4px;
button{
height: $h;
width: $h*2;
border: none;
background: blue;
border-radius: $h/2;
position: relative;
}
span {
position: absolute;
top: 2px;
left: 2px;
height: $h2;
width: $h2;
background: white;
border-radius: $h2 / 2;
transition: left 250ms;
}
button.checked {
background-color: blue;
}
button.checked > span {
left: calc(100% - #{$h2} - 2px);
}
button:focus {
outline: none;
}
</style>
<template>
<div>
<button @click="toggle" :class="{ checked: value }"><span></span></button>
<div>{{ value }}</div>
</div>
</template>
<script lang="ts">
import { ref } from "vue";
export default {
props: {
value: Boolean,
},
setup(props, context) {
const toggle = () => {
context.emit("input", !props.value);
};
return { toggle };
},
};
</script>
总结:
关于内部数据 VS 父子数据
- 内部数据是,所有的数据都是在组件内部。好处是写起来方便,坏处是没办法和外面沟通
export default {
setup() {
const checked = ref(false)
const toggle = () => {
checked.value = !checked.value
}
return { checked, toggle }
},
}
- 而第二种 Switch组件,接口 value 和 @input 事件,父子数据更常用
setup(props, context) {
const toggle = () => {
context.emit("input", !props.value);
};
return { toggle };
},
v-model 对 父子之间的数据交流进行简化
<Switch :value="y" @update:value="y = \$event"/>
可以简写成:
<Switch v-model:value="y" />