如何封装一款开关组件
1.属性
只需要传递一个布尔值,来控制开关, 并且使用v-model绑定上即可。
2.开关组件
// switchIcon.vue
<script setup>
const props = defineProps({
modelValue: {
type: Boolean,
default: true
}
})
const emits = defineEmits(['update:modelValue'])
const value = computed({
get () {
return props.modelValue
},
set (val) {
emits('update:modelValue', val)
}
})
</script>
<template>
<div>
<label class="switch">
<input type="checkbox" v-model="value">
<span class="slider"></span>
</label>
</div>
</template>
<style scoped>
.switch {
--secondary-container: #1967F2;
--primary: #fff;
font-size: 17px;
position: relative;
display: inline-block;
width: 3.7em;
height: 1.8em;
}
.switch input {
display: none;
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #BBC9C6;
transition: .2s;
border-radius: 30px;
}
.slider:before {
position: absolute;
content: "";
height: 1.4em;
width: 1.4em;
border-radius: 20px;
left: 0.2em;
bottom: 0.2em;
background-color: #fff;
transition: .4s;
}
input:checked + .slider::before {
background-color: var(--primary);
}
input:checked + .slider {
background-color: var(--secondary-container);
}
input:focus + .slider {
box-shadow: 0 0 1px var(--secondary-container);
}
input:checked + .slider:before {
transform: translateX(1.9em);
}
</style>
3.使用示例
3.1 直接使用v-model
<script setup>
import switchIcon from '@/components/mBtns/switchIcon.vue';
// 传递布尔值,表示开关状态
const on = ref(true)
// 使用watch来侦听最新的状态,并且做一些相应的处理
watch(on, (val, _) => {
console.log(val, 'va');
// 其他相应的处理
})
</script>
<template>
<switchIcon
v-model="on"
>
</switchIcon>
<div>{{ on }}</div>
</template>
3.1 v-model语法糖(vue3)
v-model绑定到组件上的时候
可以拆分为 :modelValue="on" @update:modelValue="updateModelValue"
:modelValue="on"用于实现数据的单向绑定。当v-model指令被应用到组件上时,它会将value属性值绑定到组件的prop。
@update:modelValue="updateModelValue"用于监听组件内部的变化,并将这些变化通知给父组件。在v-model指令中,它会监听组件的input事件,当这个事件触发时,就会更新绑定到v-model的变量的值。
注意: modelValue是固定的。
<script setup>
import switchIcon from '@/components/mBtns/switchIcon.vue';
const on = ref(true)
const updateModelValue = (val) => {
// 获取到最新状态
on.value = val
}
</script>
<template>
<switchIcon
:modelValue="on"
@update:modelValue="updateModelValue"
>
</switchIcon>
<div>{{ on }}</div>
</template>