小程序开关组件

前提是vant组件库不太好改,干脆就手写了一个

javascript 复制代码
<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>

效果如图

相关推荐
软件技术新观察10 小时前
企业数字化开发科普:软件定制、小程序、APP 开发全解析
人工智能·小程序
凡泰AI10 小时前
小程序容器技术解析:一个能够同时在多端APP运行同一个小程序的SDK需要关注哪些内容?
开发语言·小程序·mpaas·uni·技术实践
爱折腾的编程老炮10 小时前
潮玩小程序订单模型-一张表装下所有玩法
spring boot·小程序·uni-app
万岳科技程序员小金11 小时前
同城O2O外卖系统源码开发详解:从APP、小程序到后台管理平台的完整架构解析
小程序·架构·同城外卖系统源码·外卖app开发·外卖小程序开发·外卖软件开发·外卖平台搭建
博、、11 小时前
全民健身解决方案小程序系统开发实战:从架构设计到上线指南
小程序
2501_9151063212 小时前
Flutter iOS混淆打包详细教程与步骤
android·flutter·ios·小程序·uni-app·iphone·webview
码云数智-大飞1 天前
2026 年跨端开发决战:小程序原生 vs uni-app vs Taro 深度对比
小程序·uni-app·taro
河北清兮网络科技1 天前
直播APP开发怎么选?流媒体高端定制架构解析,避开模板与外包技术坑
小程序·架构·app·短剧·短剧app·广告联盟
上单带刀不带妹1 天前
小程序图片缓存问题:时间戳和版本号解决图片不更新
缓存·小程序·vue·uniapp