cashier-ipad/components/my-components/my-switch.vue

163 lines
3.3 KiB
Vue

<template>
<view>
<view class="q-switch-box" :style="{
backgroundColor: modelValue ? activeBgColor : inActiveBgColor,
width: width,
height: height,
borderRadius: `calc(${height} / 2)`,
}" @click.stop="changeSwitch"
:class="{disabled:disabled&&openDisabledClass}"
>
<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>
<!-- 自定义Switch:自定义左右内容 -->
<script setup>
import {
computed,
ref
} from 'vue'
const props = defineProps({
disabled:{
type:Boolean,
default:false
},
openDisabledClass:{
type:Boolean,
default:true
},
height: {
type: String,
default: '40rpx',
},
width: {
type: String,
default: '78rpx',
},
margin: {
type: String,
default: '4rpx',
},
fontSize: {
type: String,
default: '32rpx',
},
// 激活背景色
activeBgColor: {
type: String,
default: '#318AFE',
},
// 未激活背景色
inActiveBgColor: {
type: String,
default: '#ECECEC',
},
// 激活文本
showText: {
type: String,
default: '',
},
// 未激活文本
inShowText: {
type: String,
default: '',
},
// v-modal
modelValue: {
type: [Boolean,Number],
default: false,
},
})
const emits = defineEmits(['update:modelValue', 'change','click'])
// 修改switch值
function changeSwitch() {
if(props.disabled){
emits('click')
return
}
let currentVal=props.modelValue
let type=typeof currentVal
if(type==='number'){
currentVal=currentVal===0?1:0
}
if(type==='boolean'){
currentVal=!currentVal
}
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>
<style lang="scss" scoped>
.q-switch-box {
display: flex;
background-color: #eaeaea;
position: relative;
height: 100%;
&.disabled{
opacity: .5;
}
.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>