uni-item-manage/tm-vuetify/components/tm-switch/tm-switch.vue
2023-10-18 15:52:41 +08:00

253 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 开关 -->
<template>
<view @click="onclick" class="d-inline-block tm-switch " >
<view class="tm-switch-wk relative " :style="[{width:width+'rpx',height:(height+4)+'rpx'}]">
<view class="tm-switch-bg round-l-24 round-r-24 flex-between"
:class="[bgColorCusjs,loaddingState?'opacity-7':'']"
>
<view class="text-size-xs tm-switch-txt text-align-center flex-center" style="width:50%">
<text>{{text[0]?text[0]:''}}</text>
</view>
<view class="text-size-xs tm-switch-txt text-align-center flex-center" style="width:50%">
<text class="pr-8">{{text[1]?text[1]:''}}</text>
</view>
</view>
<!-- bar -->
<view class="tm-switch-wk-bar absolute round-24 white flex-center "
:style="[
{transform:changValue?`translateX(${(width-(width/2+4))}rpx)`:`translateX(2rpx)`},
{width:(width/2-4)+'rpx',height:(height-4)+'rpx'}
]"
:class="[changValue?'shadow-'+color+'-10':'',changValue?'on aniOn':'aniOff']">
<text v-if="loaddingState" class="iconfont icon-loading" :class="[loaddingState?'load':'',`text-${color_tmeme}`]"></text>
</view>
</view>
</view>
</template>
<script>
/**
* 开关
* @property {String|Boolean} value = [true|false] 同v-model一样的值如果需要双向绑定需要value.sync推荐使用v-model
* @property {String|Number|Boolean|Object} name = [] 自定义数据change时携带。
* @property {Function} change {checked,value:携带的name数据}
* @property {Boolean} disabled = [true|false] 默认false, 禁用
* @property {String} color = [] 默认primary, 主题色
* @property {Boolean} black = [true|false] 默认false, 暗黑模式
* @property {Boolean} loadding = [true|false] 默认false, 是否加载中
* @property {Array} text = [true|false] 默认: ['开','关'], 左右两边的字符
* @property {Number} width = [] 默认100,单位rpx宽度
* @property {Number} height = [] 默认50,单位rpx高度
* @property {String} offBgcolor = [] 默认:'grey-lighten-2 text-grey', 主题色可以是文字色组合来改变文字和背景色.
* @example <tm-switch v-model="checked"></tm-switch>
*
*/
export default {
name: 'tm-switch',
model: {
prop: 'value',
event: 'input'
},
props:{
value:{
type:String|Boolean,
default:false
},
name:{
type:String|Number|Boolean|Object,
default:''
},
// 禁用。
disabled: {
type:Boolean|String,
default:false
},
loadding: {
type:Boolean|String,
default:false
},
color:{
type:String,
default:'primary'
},
// 暗黑
black: {
type:Boolean|String,
default:null
},
// 左右两边的字符。
text:{
type:Array,
default:()=>{
return ['开','关']
}
},
width:{
type:String|Number,
default:100
},
height:{
type:String|Number,
default:50
},
offBgcolor:{
type:String,
default:'grey-lighten-2 text-grey'
},
// 跟随主题色的改变而改变。
fllowTheme:{
type:Boolean|String,
default:true
}
},
watch: {
value: function(newval, oldval) {
if (newval !== oldval) {
if (!this.jiancMax()) {
this.changValue = false;
return;
}
}
}
},
computed: {
black_tmeme: function() {
if (this.black !== null) return this.black;
return this.$tm.vx.state().tmVuetify.black;
},
color_tmeme:function(){
if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
return this.$tm.vx.state().tmVuetify.color;
}
return this.color;
},
changValue: {
get: function() {
return this.value;
},
set: function(newValue) {
this.$emit('input', newValue)
// 如果不想用v-model. 直接使用value,需要:value.sync
this.$emit('update:value', newValue);
}
},
loaddingState:function(){
return this.loadding;
},
bgColorCusjs(){
if(this.disabled) {
if(this.black_tmeme){
return 'grey-darken-4 bk';
}else{
return this.color_tmeme+' opacity-5';
}
}
if(this.black_tmeme){
if(this.changValue) return this.color_tmeme + ' bk ';
if(!this.changValue) return 'grey-darken-1 bk ';
}else{
if(this.changValue) return this.color_tmeme + ' text-white ';
if(!this.changValue) return this.offBgcolor;
}
}
},
data() {
return {
animationOn:null,
animationOff:null,
aniData:null,
};
},
mounted() {
},
methods: {
// 检查是否超过了最大选择。
jiancMax() {
if(this.disabled) return false;
return true;
},
onclick(e) {
if (this.disabled||this.loaddingState) return;
if (!this.jiancMax()) {
return;
}
this.changValue = !this.changValue;
this.change();
},
change() {
this.$nextTick(function(){
this.$emit('change', {
checked: this.changValue,
value: this.name
});
})
}
},
}
</script>
<style lang="scss" scoped>
.tm-switch{
vertical-align: middle;
.tm-switch-wk{
// width: 100rpx;
// height: 52rpx;
}
.tm-switch-bg{
width: 100%;
height: 100%;
transition: all 0.5s;
.tm-switch-txt{
// width: 50upx;
height: 100%;
// line-height: 48upx;
}
}
.tm-switch-wk-bar{
left: 4rpx;
top: 4rpx;
// width:40rpx;
// height: 46rpx;
transition: all 0.35s ease-in-out;
.load{
animation: xhRote 0.8s infinite linear;
}
}
}
.aniOn{
left: inherit;
}
.aniOff{
right: inherit;
}
@keyframes xhRote{
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
</style>