1
0
зеркало из https://github.com/ialley-workshop-open/uni-halo.git synced 2026-06-11 12:49:30 +08:00
Files
uni-halo/tm-vuetify/components/tm-stepper/tm-stepper.vue
T
2022-12-06 15:08:29 +08:00

316 строки
9.2 KiB
Vue
Исходник Ответственный История

Этот файл содержит неоднозначные символы Юникода
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 class="tm-stepper d-inline-block">
<view class="flex-center" :style="{ width: `${width}rpx` }">
<view :class="[isJianDisabled||disabled?'opacity-6 gray':'']">
<tm-button @touchcancel="endlongpressEvent" @touchend="endlongpressEvent"
@touchstart="$emit('touchstart', 'minus')" @longpress="longpressEvent('-')" :fllowTheme="fllowTheme"
:disabled="isJianDisabled || disabled ? true : false"
:shadow="isJianDisabled || disabled ? 0 : shadwo_num" :black="black_tmeme" @click="setStep('-')"
:item-class="circular?' pa-0':` round-l-${round} `" icon-size="24" :round="circular?round:0"
:theme="disabled ? '' : color_tmeme" :width="height" :height="height" block icon="icon-minus">
</tm-button>
</view>
<input v-if="fixed!=0" @blur="inputVal" @input="inputVal" :disabled="(disabled||disabledInput)"
v-model="setVal" type="digit" :style="{ height: `${height}rpx`, width: `calc(100% - ${height}rpx)` }"
class="text-align-center text-size-n fulled"
:class="[`text-${font_color}`, black_tmeme&&!circular ? 'grey-darken-4 bk' : '',black_tmeme? 'text-grey-lighten-4' : '',circular?'':'grey-lighten-4']" />
<input v-if="fixed==0" @blur="inputVal" @input="inputVal" :disabled="(disabled||disabledInput)"
v-model="setVal" type="number" :style="{ height: `${height}rpx`, width: `calc(100% - ${height}rpx)` }"
class="text-align-center grey-lighten-4 text-size-n fulled"
:class="[`text-${font_color}`, black_tmeme&&!circular ? 'grey-darken-4 bk' : '',black_tmeme? 'text-grey-lighten-4' : '',circular?'':'grey-lighten-4']" />
<view :class="[isAddDisabled||disabled?'opacity-6 gray':'']">
<tm-button @touchcancel="endlongpressEvent" @touchend="endlongpressEvent"
@touchstart="$emit('touchstart', 'add')" @longpress="longpressEvent('+')" :fllowTheme="fllowTheme"
:shadow="isAddDisabled || disabled ? 0 : shadwo_num" :black="black_tmeme" @click="setStep('+')"
:item-class="circular?' pa-0':` round-r-${round} `" icon-size="24" :round="circular?round:0"
:theme="disabled ? '' : color_tmeme" :disabled="isAddDisabled || disabled ? true : false"
:width="height" :height="height" block icon="icon-plus"></tm-button>
</view>
</view>
</view>
</template>
<script>
/**
* 步进器
* @property {String|Number} value = [] 默认:'',值,推荐使用value.sync或者v-model
* @property {Boolean} disabled = [] 默认:false,是否禁用
* @property {Boolean} black = [] 默认:false,是否暗黑模式。
* @property {Number|String} step = [] 默认:1 步幅。
* @property {String} color = [] 默认:primary 主题色。
* @property {String} fontColor = [] 默认:black 输入框的文字主题色。
* @property {String|Number} round = [] 默认:3 圆角。
* @property {String|Number} shadow = [] 默认:3 圆角。
* @property {String|Number} max = [] 默认:999 最大值。
* @property {String|Number} min = [] 默认:0 最小值。
* @property {String|Number} width = [] 默认:200 宽度,单位rpx。
* @property {String|Number} height = [] 默认:70 高度,单位rpx。
* @property {String} name = [] 默认:'',提交表单时的的字段名称标识
* @property {Boolean|String} disabledInput = [] 默认:false,是否禁用输入框
* @property {Boolean|String} circular = [] 默认:false,按钮四角是否跟随圆角
* @property {Number} fixed = [] 默认:0 小数点位数
* @example <tm-stepper value="50"></tm-stepper>
*/
import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
export default {
components: {
tmButton
},
name: 'tm-stepper',
model: {
prop: 'value',
event: 'input'
},
props: {
value: {
type: Number | String,
default: 0
},
//提交表单时的的字段名称
name: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
//禁用输入功能
disabledInput: {
type: Boolean | String,
default: false
},
black: {
type: Boolean | String,
default: null
},
// 步幅,默认1
step: {
type: Number,
default: 1
},
//固定小数点位数,0表示整数
fixed: {
type: Number,
default: NaN
},
color: {
type: String,
default: 'primary'
},
fontColor: {
type: String,
default: 'black'
},
round: {
type: String | Number,
default: 3
},
circular: {
type: Boolean | String,
default: false
},
shadow: {
type: String | Number,
default: 3
},
// 跟随主题色的改变而改变。
fllowTheme: {
type: Boolean | String,
default: true
},
max: {
type: Number | String,
default: 999
},
min: {
type: Number | String,
default: 0
},
height: {
type: Number | String,
default: 60
},
width: {
type: Number | String,
default: 180
},
//回调函数。默认返回true即增减,否则不执行增减。
callback: {
type: Function | Object | Boolean,
default: true
}
},
data() {
return {
setVal: '',
timeid: 598985656
};
},
mounted() {
this.setVal = this.value;
},
watch: {
value: function(val) {
this.jianchData(parseFloat(val));
}
},
computed: {
isJianDisabled() {
if (isNaN(parseInt(this.setVal))) return false;
if (parseInt(this.setVal) <= this.min) return true;
return false;
},
isAddDisabled() {
if (isNaN(parseInt(this.setVal))) return false;
if (parseInt(this.setVal) >= this.max) return true;
return false;
},
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;
},
font_color: function() {
if (this.fontColor) return this.fontColor;
return this.color;
},
shadwo_num: function() {
if (typeof this.shadow !== 'undefined') return this.shadow;
return 3;
}
},
destroyed() {
clearInterval(this.timeid);
},
methods: {
async setStep(ty) {
if (this.disabled) return;
if (typeof this.callback !== 'boolean' && this.callback !== true) {
uni.showLoading({
title: '...',
mask: true
})
let p = await this.callasync();
uni.hideLoading();
if (p !== true) return;
}
this.$nextTick(function() {
var val = parseFloat(this.value);
if (!isNaN(this.fixed) && this.fixed > 0) {
val = val.toFixed(this.fixed)
if (isNaN(val) || val == 0 || val == '0' || val == '' || !val) {
val = '0.' + this.strWidth(this.fixed) + this.step
}
val = parseFloat(val)
let setval = '0.' + this.strWidth(this.fixed) + this.step
setval = parseFloat(setval);
if (ty == '+') {
val += setval
} else {
val -= setval
}
} else if (!isNaN(this.fixed) && this.fixed == 0) {
val = val.toFixed(this.fixed)
val = parseInt(val)
if (ty == '+') {
val += this.step
} else {
val -= this.step
}
} else if (isNaN(this.fixed)) {
if (ty == '+') {
val += this.step
} else {
val -= this.step
}
}
if (val < 0) {
if (val <= this.min) {
val = this.min;
}
clearInterval(this.timeid);
} else if (val >= this.max) {
val = this.max;
clearInterval(this.timeid);
}
const realVal = val;
this.setVal = isNaN(realVal) ? '' : String(val);
this.$emit('input', this.setVal);
this.$emit('update:value', this.setVal);
this.$emit('change', this.setVal);
});
},
inputVal(e) {
var val = parseFloat(e.detail.value)
this.jianchData(val);
},
strWidth(len) {
let v = '';
for (let i = 0; i < len - 1; i++) {
v += '0';
}
return v;
},
jianchData(val) {
this.$nextTick(function() {
if (!isNaN(this.fixed) && this.fixed > 0) {
val = val.toFixed(this.fixed)
if (isNaN(val) || val == 0 || val == '0' || val == '' || !val) {
val = '0.' + this.strWidth(this.fixed) + this.step
}
} else if (!isNaN(this.fixed) && this.fixed == 0) {
val = val.toFixed(this.fixed)
}
const realval = val;
if (val < this.min) {
val = String(this.min);
}
if (val > this.max) {
val = String(this.max);
}
this.setVal = isNaN(parseFloat(realval)) ? '' : String(val);
this.$emit('input', this.setVal);
this.$emit('update:value', this.setVal);
this.$emit('change', this.setVal);
});
},
longpressEvent(ty) {
if (this.disabled) return;
let t = this;
clearInterval(this.timeid);
this.timeid = setInterval(async function() {
await t.setStep(ty);
}, 250);
},
endlongpressEvent(ty) {
clearInterval(this.timeid);
},
//异步回调
async callasync() {
let verify = this.callback;
verify = await verify()
if (typeof verify === 'function') {
verify = await verify()
}
if (typeof verify !== 'boolean') verify = true;
return verify;
}
}
};
</script>
<style lang="scss"></style>