小程序开关组件
前提是vant组件库不太好改,干脆就手写了一个
<template>
<view class="switch-container" @click="toggleOrder">
<view :class="['switch-text', 'left-text', { 'left-textChoose': isReverseOrder }]"
>{{ leftText }}</view
>
<view class="switch-slider" :style="sliderStyle"></view>
<view :class="['switch-text', 'right-text', { 'right-textChoose': !isReverseOrder }]"
>{{ rightText }}</view
>
</view>
</template>
<script setup>
import { ref, computed } from 'vue';
const props = defineProps({
leftText: {
type: String,
default: ''
},
rightText: {
type: String,
default: ''
}
});
const isReverseOrder = ref(true);
const emit = defineEmits(['getValue']);
// 计算滑块的位置
const sliderStyle = computed(() => {
// 滑块完全在左侧时偏移量为0%,完全在右侧时偏移量为100%
return {
transform: `translateX(${isReverseOrder.value ? '100%' : '0%'})`
};
});
// 切换开关状态
function toggleOrder() {
isReverseOrder.value = !isReverseOrder.value;
console.log(isReverseOrder.value);
emit('getValue', isReverseOrder.value);
}
</script>
<style scoped>
.switch-container {
border: 2px solid #eeeeee;
display: flex;
align-items: center;
width: 72px;
height: 28px;
background-color: #eeeeee;
border-radius: 20px;
overflow: hidden;
position: relative; // 滑块绝对定位
}
.switch-text {
flex: 1; //使文本元素占据剩余空间的一半
display: flex;
justify-content: center;
align-items: center;
user-select: none;
position: relative; //为了可能的z-index调整
z-index: 2; // 确保文本在滑块之上
}
.left-text {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 10px;
color: #25292f;
}
.left-textChoose {
font-family: PingFang SC;
font-weight: 400;
font-size: 10px;
color: #25292f;
}
.right-text {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 10px;
color: #25292f;
}
.right-textChoose {
font-family: PingFang SC;
font-weight: 400;
font-size: 10px;
color: #25292f;
}
.switch-slider {
width: 50%; // 滑块宽度为容器宽度的一半
height: 24px;
background-color: #fff;
transition: transform 0.3s ease-in-out; // 过渡效果
border-radius: 20px;
position: absolute; // 绝对定位以覆盖整个容器
left: 0; //初始位置
top: 0;
bottom: 0;
z-index: 1; // 确保滑块在文本之下
}
</style>
效果如图