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>
|