179 lines
5.0 KiB
Vue
179 lines
5.0 KiB
Vue
<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>
|