环境:vue3 + uniapp
如果是vue2也可以自己改造,语法稍微修改一下就行
组件功能:
可自定义左右两边内容:
组件代码如下:
<!-- 自定义Switch:自定义左右内容 -->
<script setup>
import { computed, ref } from 'vue'
const props = defineProps({
height: {
type: String,
default: '44rpx',
},
width: {
type: String,
default: '110rpx',
},
margin: {
type: String,
default: '4rpx',
},
fontSize: {
type: String,
default: '32rpx',
},
// 激活背景色
activeBgColor: {
type: String,
default: '#1F78F5',
},
// 未激活背景色
inActiveBgColor: {
type: String,
default: '#EAEAEA',
},
// 激活文本
showText: {
type: String,
default: '显示',
},
// 未激活文本
inShowText: {
type: String,
default: '隐藏',
},
// v-modal
modelValue: {
type: Boolean,
default: false,
},
})
const emits = defineEmits(['update:modelValue', 'change'])
// 修改switch值
function changeSwitch() {
let currentVal = !props.modelValue
console.log('111')
emits('update:modelValue', currentVal)
emits('change', currentVal)
}
// 圆圈半径
let circleRadius = computed(() => {
return `calc(((${props.height} / 2) - ${props.margin})* 2)`
})
// 动画效果
let switchAnimation = computed(() => {
let obj = {
transition: `transform 0.3s`,
transform: 'translateX(0)',
}
//激活
if (!props.modelValue) {
let innerRadius = `((${props.height} / 2) - ${props.margin})` //圆圈半径
let moveValue = `calc(${props.width} - ${props.margin} * 2 - (${innerRadius} * 2))` //偏移距离 总宽度 - 圆圈左右边距 - 圆圈宽度
console.log('move-value', moveValue)
obj.transform = `translateX(${moveValue})`
} else {
// 未激活
obj.transform = 'translateX(0)'
}
return obj
})
</script>
<template>
<view>
<view
class="q-switch-box"
:style="{
backgroundColor: modelValue ? activeBgColor : inActiveBgColor,
width: width,
height: height,
borderRadius: `calc(${height} / 2)`,
}"
@click.stop="changeSwitch"
>
<view
v-show="!modelValue"
class="before"
:style="{
left: `calc(${margin} * 2)`,
}"
><slot name="left">{{ inShowText }}</slot></view
>
<!-- 圆圈 -->
<view
class="circle-inner"
:style="{
margin: margin,
width: circleRadius,
height: circleRadius,
backgroundColor: '#ffffff',
...switchAnimation,
}"
></view>
<view
v-show="modelValue"
class="after"
:style="{
right: `calc(${margin} * 2)`,
}"
><slot name="right">{{ showText }}</slot></view
>
</view>
</view>
</template>
<style lang="scss" scoped>
.q-switch-box {
display: flex;
background-color: #eaeaea;
position: relative;
height: 100%;
.circle-inner {
border-radius: 50%;
}
.before {
position: absolute;
color: #bbbbbb;
font-size: 28rpx;
display: flex;
height: 100%;
align-items: center;
}
.after {
position: absolute;
font-size: 28rpx;
color: #ffffff;
display: flex;
height: 100%;
align-items: center;
}
}
</style>
使用效果如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c5fc443d54d54763a65e956902280919.png
使用代码如下:组件引入(uniapp这边可以使用easycom定义引入规则,单页面就不要再引入了,需要单独引入的自己import就行)
组件名称:self-switch
这边使用到了三方组件,需要的只要复制 </部分就好了
<script setup>
import { ref } from 'vue'
import { copyToClipboard } from '@/utils/utils.js'
function change(val) {
console.log('修改', val)
}
let demo1 = ref(true)
let demo2 = ref(true)
let demo3 = ref(true)
let demo4 = ref(true)
function copyCode(content) {
copyToClipboard(content)
}
</script>
<template>
<view>
<u-cell-group>
<u-cell
icon="thumb-up"
title="基本用法"
>
<template #right-icon
><self-switch v-model="demo1" @change="change"></self-switch></template
></u-cell>
<u-cell
icon="thumb-up"
title="自定义文本"
>
<template #right-icon
><self-switch
v-model="demo2"
inShowText="左"
showText="右"
@change="change"
></self-switch></template
></u-cell>
<u-cell
icon="thumb-up"
title="自定义选中颜色"
>
<template #right-icon
><self-switch
v-model="demo4"
activeBgColor="#C74067"
@change="change"
></self-switch></template
></u-cell>
<u-cell
icon="thumb-up"
title="自定义插槽内容"
>
<template #right-icon
><self-switch v-model="demo3" @change="change">
<template #left>
<u-icon name="thumb-up" color="#0000000"></u-icon>
</template>
<template #right
><u-icon name="thumb-down" color="#0000000"></u-icon
></template>
</self-switch> </template
></u-cell>
</u-cell-group>
</view>
</template>
<style lang="scss" scoped></style>