scale组件代码(部分class样式使用到了uview1.0的样式)
<template><view><view class="scale"><view class="pointer u-flex-col u-col-center"><u-icon name="arrow-down-fill" size="26" color="#33B4C2"></u-icon></view><view class="ruler"><scroll-view class="scroll" :scroll-x="true" :scrollLeft="scrollLeft" @scroll="scaleScroll"@touchstart="touchstart" @touchend="touchend"><view class="u-col-top" style="display: inline-flex;padding: 0 calc(50%);"><template v-for="(item,index) in scale"><view :class="['line',item%10==0?'int':(item%5==0?'middle':'')]":style="{width: `${width}rpx`}" ><view class="value" v-if="item%10==0"><text>{{item/10}}</text></view></view></template></view></scroll-view></view></view></view>
</template>
javascript"><script>export default {name: 'Scale',components: {},props: {value: {type: String,default: '0.0'},// 最小值min: {type: Number,default: 0,},// 最大值max: {type: Number,default: 100,},// 每个刻度宽度width: {type: Number,default: 10,},},data() {return {scrollLeft: 0,//left:0,//isScroll: true,//用户是否停止操作scrollTimer:null,manual:false,implement:false,//是否还在滚动};},computed: {scale() {//计算出标尺所有刻度let arr = [];for (let i = this.min*10; i <= this.max * 10; i++) {arr.push(i);}return arr;},widthPx(){//每个刻度宽度return uni.upx2px(this.width);}},created() {//数据回显let val = parseFloat(this.value);if(val<=this.min){this.$emit('input',this.min.toFixed(1))}else{this.scroll()}},methods: {//滚动scaleScroll(e) {if(!this.manual){return;}//还在滚动中this.implement = true;//获取滚动距离let scrollLeft = e.detail.scrollLeft;this.left = scrollLeft;//计算对应值let index = (scrollLeft / this.widthPx).toFixed(0);let value = (this.scale[parseInt(index)]/10).toFixed(1);this.$emit('input', value);//避免重复执行@scrollclearTimeout(this.scrollTimer);this.scrollTimer = setTimeout(()=>{//判断用户是否已经停止操作if(this.isScroll){this.scroll()}},300)},//开始滚动touchstart(e) {this.isScroll = false;this.manual = true;},//用户停止操作touchend(e) {this.isScroll = true;this.implement = false;//解决scaleScroll已经执行完,但标尺未吸附问题setTimeout(()=>{//判断是否还在滚动并且是否已经吸附if(this.left!=this.scrollLeft&&!this.implement){this.scroll()}},300)},//标尺吸附scroll(){//吸附时禁止执行@scaleScroll,防止一直滚动,数据异常this.manual = false;//计算滚动距离let index = this.scale.indexOf(parseInt(this.value*10));this.scrollLeft = index * this.widthPx;}},};
</script>
<style lang="scss" scoped>.scale {width: 100%;.pointer {position: relative;padding-bottom: 12rpx;&::after {position: absolute;z-index: 9;top: 38rpx;content: '';display: block;width: 4rpx;height: 78rpx;background: #33B4C2;}}.ruler {height: 114rpx;.scroll {height: 100%;width: 100%;::-webkit-scrollbar {width: 0;height: 0;color: transparent;}.line {position: relative;height: 36rpx;display: flex;flex-direction: column;align-items: center;&:last-child{width: 2rpx !important;}&::after {content: '';position: absolute;display: block;width: 2rpx;height: 100%;top: 0;left: 0;background: #C1E8ED;}.value {left: -23rpx;position: absolute;bottom: -48rpx;width: 46rpx;height: 36rpx;font-size: 26rpx;font-family: PingFang SC-Regular, PingFang SC;font-weight: 400;color: #C1C1C1;line-height: 36rpx;text-align: center;}}.int {height: 66rpx;}.middle {height: 50rpx;}}}}
</style>
使用方式
javascript">
<script>import Scale from '@/components/Scale/index.vue';export default {components: {Scale},data() {return {value:'10.0',}},}
</script>
<view class="value"><text>{{value}}</text></view><scale v-model="value" :width="16"></scale>
<style lang="scss">.value{padding: 36rpx 0 20rpx;font-size: 36rpx;font-family: PingFang SC-Regular, PingFang SC;font-weight: 400;color: #33B4C2;line-height: 50rpx;text-align: center;&::after{content: ' 公斤';height: 50rpx;font-size: 24rpx;font-family: PingFang SC-Regular, PingFang SC;font-weight: 400;color: #33B4C2;line-height: 50rpx;}}
</style>