公共组件Switch按钮,开箱即用
<!-- 使用 -->
<div
class="item"
v-for="(item, index) in list"
:key="index"
>
<span class="name">{{ item.name }}</span>
<DiySwitch
class="diy__switch"
@change="changeOpenModel(item)"
v-model="item.open"
></DiySwitch>
</div>
let code = "3e0d967d-70c5-4181-a36b-a85bef49af07"
<!-- DiySwitch.vue -->
<template>
<div class="diy-switch" :class="{ 'is-checked': checked }">
<input
class="diy-switch__input"
ref="input"
type="checkbox"
:checked="checked"
@change="handleInput"
:true-value="trueValue"
:false-value="falseValue"
/>
<span class="diy-switch_action"></span>
</div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, computed, ref, nextTick } from "vue";
const props = defineProps({
modelValue: {
//绑定值,必须等于active-value或inactive-value,默认为Boolean类型 如果是vue2 这里绑定是 `value`
type: [Number, String, Boolean],
},
trueValue: {
//switch 打开时的值 可以自定义组件打开的时的值
type: [Number, String, Boolean],
default: true,
},
falseValue: {
// switch 关闭时的值 可以自定义组件关闭的时的值
type: [Number, String, Boolean],
default: true,
},
activeColor: {
//switch 打开时的背景色
type: [String],
default: "#146fff",
},
});
const emits = defineEmits(["update:modelValue", "change"]);
onMounted(() => {});
onBeforeUnmount(() => {});
//获取input元素
const input = ref(null);
//判断当前组件是否是打开状态
const checked = computed(() => {
//因为可以自定义打开和关闭的值 所以这里必须判断 v-model绑定的值 === 组件自定义打开的值
return props.modelValue === props.trueValue;
});
//input事件 获取当前input事件
const handleInput = () => {
nextTick(() => {
const val = input.value.checked;
emits("update:modelValue", val); // 开关点击后的状态传给v-model
emits("change", val); //给组件增加change 事件
});
};
</script>
<style lang="less" scoped>
.diy-switch {
position: relative;
width: 20px;
height: 12px;
transition: background 0.2s;
background: #284269;
border-radius: 2px 2px 2px 2px;
border: 1px solid #9ab8e3;
display: inline-flex;
align-items: center;
vertical-align: middle;
.diy-switch__input {
cursor: pointer;
position: relative;
z-index: 1;
margin: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.diy-switch_action {
position: absolute;
transition: 0.2s;
left: 2px;
top: 2px;
z-index: 0;
width: 8px;
height: 8px;
background: #9ab8e3;
border-radius: 2px 2px 2px 2px;
}
}
.diy-switch.is-checked {
background: v-bind(activeColor);
.diy-switch_action {
position: absolute;
background: #fff;
margin-left: 8px;
}
}
</style>
预览