Vue3开关按钮自定义组件实现

SwitchOn.vue

<template>

    <div class="switch-container">

        <div id="ecllipse" :class="ecllipseInit" @click="$emit('switch')">

            <div id="circle" :class="circleInit"></div>

            <div id="word" :class="wordInit">{{ wordKey }}</div>

        </div>

    </div>

</template>



<script setup>

import { computed, toRefs } from 'vue';

defineOptions({

    inheritAttrs: false // 禁止自动继承父组件中的标签属性

})

// 接收父组件传入的属性width,toggle

const props = defineProps({

    'width': {

        type: String,

        default: '100px',

    }

    ,

    'toggle': {

        type: Boolean,

        default: true,

    }

});



// 注册开关事件

defineEmits(['switch']);

// 本地使用与父组件绑定的属性(如:width,toggle)和通过发射事件switch绑定的方法(如:doToggleSwitch)

const { width, toggle } = toRefs(props);

// class样式属性绑定并初始化

const ecllipseInit = computed(() => {

    return toggle.value ? 'ecllipse-right' : 'ecllipse-left';

});

const circleInit = computed(() => {

    return toggle.value ? 'circle-right' : 'circle-left';

});

const wordInit = computed(() => {

    return toggle.value ? 'word-left' : 'word-right';

});

const wordKey = computed(() => {

    return toggle.value ? 'ON' : 'OFF';

});

// 其余标签属性绑定并初始化

const height = computed(() => {

    return 0.4 * width.value.replace('px', '') + 'px';

})

const borderRadius = computed(() => {

    return height.value.replace('px', '') / 2 + 'px';

})

const fontSize = computed(() => {

    return (0.2 * width.value.replace('px', '') + 6) + 'px';

})

const lrdistance = computed(() => {

    return 0.08 * width.value.replace('px', '') + 'px';

})

</script>



<style scoped>

.switch-container {

    margin: auto;

    width: v-bind(width);

    height: v-bind(height);

    position: relative;

}



#ecllipse {

    width: v-bind(width);

    height: v-bind(height);

    border-radius: v-bind(borderRadius);

    position: absolute;

    box-shadow: 0px 0px 3px #000000;

}



#circle {

    width: v-bind(height);

    height: v-bind(height);

    background-color: #ffffff;

    border-radius: 50%;

    position: absolute;

    right: 0px;

}



#word {

    width: v-bind(width);

    font-size: v-bind(fontSize);

    line-height: v-bind(height);

    position: relative;

    color: #ffffff;

}



.circle-left {

    left: 0px;

}



.circle-right {

    right: 0px;

}



.word-left {

    text-align: left;

    left: v-bind(lrdistance);



}



.word-right {

    text-align: right;

    right: v-bind(lrdistance);

}



.ecllipse-right {

    background-color: #008000;

}



.ecllipse-left {

    background-color: #416f41;

}

</style>

SwitchOn.vue自定义组件使用:App.vue

<script setup lang="js">

import SwitchButton from './SwitchButton.vue';

import { ref } from 'vue';

const toggled = ref(true);

function doToggleSwitch() {

  toggled.value = !toggled.value;

}

</script>

<template>

    <switch-button :toggle="toggled" @switch="doToggleSwitch"></switch-button>

</template>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南腔北调-pilmar

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值