first
This commit is contained in:
158
components/my-components/my-switch.vue
Normal file
158
components/my-components/my-switch.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<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}"
|
||||
>
|
||||
<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
|
||||
},
|
||||
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'])
|
||||
// 修改switch值
|
||||
function changeSwitch() {
|
||||
if(props.disabled){
|
||||
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>
|
||||
Reference in New Issue
Block a user