glhcp/business/components/b-switch/b-switch.vue

179 lines
5.0 KiB
Vue
Raw Normal View History

2023-08-10 06:59:52 +00:00
<template>
<view class="switch" @tap="onClick" :style="[switchStyle]">
<!-- 背景 -->
<view class="switch--bg flex br60 row-around">
<!-- 文字 -->
<view class="switch--text br60 sm flex row-left p-l-20">
<view :class="value == 1 ? 'ani2':'ani1'" class="primary">{{firstText}}</view>
<view :class="value == 0 ? 'ani2':'ani1'" class="lighter">{{lastText}}</view>
</view>
<!-- 滑块 -->
<view class="switch--slider br60" :class="value == 1 ? 'open':'close'"></view>
</view>
</view>
</template>
<script>
/**
* switch 开关选择器
*/
export default {
name: "u-switch",
props: {
// 是否为加载中状态
loading: {
type: Boolean,
default: false
},
firstText: {
type: [Number, String],
default: '营业中'
},
lastText: {
type: [Number, String],
default: '暂停营业'
},
// 是否为禁用装填
disabled: {
type: Boolean,
default: false
},
// 打开时的背景颜色
activeColor: {
type: String,
default: '#f2f2f2'
},
// 关闭时的背景颜色
inactiveColor: {
type: String,
default: '#ffffff'
},
// 通过v-model双向绑定的值
value: {
type: [Number, String],
default: 1
},
// 是否使手机发生短促震动目前只在iOS的微信小程序有效(2020-05-06)
vibrateShort: {
type: Boolean,
default: true
},
// 打开选择器时的值
activeValue: {
type: [Number, String, Boolean],
default: true
},
// 关闭选择器时的值
inactiveValue: {
type: [Number, String, Boolean],
default: false
},
},
data() {
return {
}
},
computed: {
switchStyle() {
let style = {};
style.fontSize = this.size + 'rpx';
style.backgroundColor = this.value ? this.activeColor : this.inactiveColor;
return style;
},
loadingColor() {
return this.value ? this.activeColor : null;
}
},
methods: {
onClick() {
if (!this.disabled && !this.loading) {
// 使手机产生短促震动微信小程序有效APP(HX 2.6.8)和H5无效
if (this.vibrateShort) uni.vibrateShort();
this.$emit('input', this.value == 1 ? 0 : 1);
// 放到下一个生命周期因为双向绑定的value修改父组件状态需要时间且是异步的
this.$nextTick(() => {
this.$emit('change', {
value: this.value == 1 ? this.activeValue : this.inactiveValue,
text: this.value
});
})
}
}
}
};
</script>
<style lang="scss" scoped>
.switch {
width: 150rpx;
height: 40rpx;
border-radius: 60rpx;
position: relative;
border-radius: 40rpx;
&--slider {
width: 24rpx;
height: 24rpx;
border-radius: 50%;
right: 12rpx;
top: 50%;
z-index: 101;
transform: translateY(-50%);
transition: .2s linear;
position: absolute;
}
.open {
background-color: #01D739;
}
.close {
background-color: #999;
}
.ani1 {
transition: all .3s;
position: absolute;
left: -20rpx;
opacity: 0;
}
.ani2 {
transition: all .5s;
position: absolute;
left: 20rpx;
opacity: 1;
}
&--bg {
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 100;
position: relative;
position: absolute;
background-color: $-color-white;
}
&--text {
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1002;
font-size: 22rpx;
position: relative;
position: absolute;
.primary {
color: $-color-primary;
}
}
}
</style>