uni-appuin-appuni-app交流圈

拓展组件uni-number-box使用过程中问题汇总

2019-08-15  本文已影响4人  瑟闻风倾

1. 拓展组件uni-number-box的输入框高度超出

image.png
.uni-numbox__value {
        position: relative;
        background-color: #fff;
        width: 80upx;
        height: 100%;
        text-align: center;
        padding: 0;
        /* 解决app端输入框高度超出问题 */
        min-height: 1.2rem;
}
/* 解决app端输入框高度超出问题(未实现) */
/* .uni-numbox input{
    height: 100%;
    line-height: 70upx;
} */

2. 拓展组件uni-number-box在循环体中使用时

(1) 测试数据:

styleInfo:{
    //"num": "10",
    "num": 10,
},
processList:[
                {
                    "name": "做领子做领子做领子",
                    "process_no": "GX00003",
                    "price": "1.20",
                    "std_time": "36",
                    "process_id": "3",
                    "reworkNumber":0
                },
                {
                    "process_id": "6",
                    "name": "接后片接后片接后片接后片",
                    "process_no": "GX00006",
                    "price": "0.50",
                    "std_time": "30",
                    "reworkNumber":0
                },
                {
                    "process_id": "7",
                    "name": "水洗标水洗标水洗标水洗标水洗标水洗标",
                    "process_no": "GX00007",
                    "price": "0.80",
                    "std_time": "30",
                    "reworkNumber":0
                },
                {
                    "process_id": "8",
                    "name": "接后摆接后摆",
                    "process_no": "GX00007",
                    "price": "0.70",
                    "std_time": "31",
                    "reworkNumber":0
                }
],

(2)

<view class="uni-flex flex-sub uni-column bg-white padding-right-sm" style="height: 100%;border-right: 5px solid #eee;">
    <label class="uni-list-cell padding-tb-sm">
        <view class="jk-list-header flex-sub" style="text-align: center;">序号</view>
        <view class="jk-list-header flex-treble" style="text-align: center;">工序名称</view>
        <view class="jk-list-header flex-twice" style="text-align: center;">返工件数</view>
    </label>
    <scroll-view class="uni-center center-box" style="overflow: scroll;height: 80%;" scroll-y="true">
        <label class="uni-list-cell padding-tb-sm" v-for="(item,index) in processList" :key="item.process_id">
            <view class="jk-list-content flex-sub">{{index + 1}}</view>
            <view class="jk-list-content flex-treble text-cut" style="text-align: left;">{{item.name}}</view>
            <view class="jk-list-content flex-twice">
                <uni-number-box :value="item.reworkNumber"  :min="0" :max="styleInfo.num" @change="changeReworkNumber(item.process_id,item.reworkNumber)"></uni-number-box>
            </view>
        </label>
    </scroll-view>
</view>

注意valueminmax为数值型,若服务器返回为字符串需先转化为整型。
(3) 效果

效果.png
(4) 问题:点击事件无法动态修改每个item的reworkNumber(reworkNumber恒为初值0,双向绑定无效)
changeReworkNumber:function(id,reworkNumber){
    console.log("changeReworkNumber:" + id + "," + reworkNumber);
    var items = this.processList;
    console.log("processList-before:" + JSON.stringify(_self.processList));
    for (var i = 0; i < items.length; i++) {
        const item = items[i];  
        if(event.cid == item.process_id){
            this.$set(item,'reworkNumber',event.value);
        }
    }
    console.log("processList-after:" + JSON.stringify(_self.processList));
},

(5) 解决:修改源码nui-number-box.vue

<uni-number-box :value="item.reworkNumber" @change="changeReworkNumber" :cid="item.process_id"></uni-number-box>
changeReworkNumber:function(event){
    console.log("changeReworkNumber:" + JSON.stringify(event));
    var items = this.processList;
    console.log("processList-before:" + JSON.stringify(_self.processList));
    for (var i = 0; i < items.length; i++) {
        const item = items[i];  
        if(event.cid == item.process_id){
            this.$set(item,'reworkNumber',event.value);
        }
    }
    console.log("processList-after:" + JSON.stringify(_self.processList));
},

备注

<template>
    <view class="uni-numbox">
        <view class="uni-numbox__minus" :class="{'uni-numbox--disabled': disableSubtract||disabled}" @click="_calcValue('subtract')">-</view>
        <input class="uni-numbox__value" type="number" :disabled="disabled" :value="inputValue" @blur="_onBlur">
        <view class="uni-numbox__plus" :class="{'uni-numbox--disabled': disableAdd||disabled}" @click="_calcValue('add')">+</view>
    </view>
</template>
<script>
    export default {
        name: 'uni-number-box',
        props: {
            value: {
                type: Number,
                default: 1
            },
            min: {
                type: Number,
                default: 0
            },
            max: {
                type: Number,
                default: 100
            },
            step: {
                type: Number,
                default: 1
            },
            disabled: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                inputValue: this.value
            }
        },
        computed: {
            disableSubtract() {
                return this.inputValue <= this.min
            },
            disableAdd() {
                return this.inputValue >= this.max
            }
        },
        watch: {
            value(val) {
                this.inputValue = val;
            },
            inputValue(val) {
                     this.$emit('change', val);
            }
        },
        methods: {
            _calcValue(type) {
                if (this.disabled) {
                    return
                }
                const scale = this._getDecimalScale()
                let value = this.inputValue * scale
                let step = this.step * scale
                if (type === 'subtract') {
                    value -= step
                } else if (type === 'add') {
                    value += step
                }
                if (value < this.min || value > this.max) {
                    return
                }
                this.inputValue = value / scale;
            },
            _getDecimalScale() {
                let scale = 1
                // 浮点型
                if (~~this.step !== this.step) {
                    scale = Math.pow(10, (this.step + '').split('.')[1].length)
                }
                return scale
            },
            _onBlur(event) {
                let value = event.detail.value
                if (!value) {
                    this.inputValue = 0
                    return
                }
                value = +value;
                if (value > this.max) {
                    value = this.max
                } else if (value < this.min) {
                    value = this.min
                }
                this.inputValue = value
            }
        }
    }
</script>
<style>
    @charset "UTF-8";

    .uni-numbox {
        display: inline-flex;
        flex-direction: row;
        justify-content: flex-start;
        height: 70upx;
        position: relative
    }

    .uni-numbox:after {
        content: '';
        position: absolute;
        transform-origin: center;
        box-sizing: border-box;
        pointer-events: none;
        top: -50%;
        left: -50%;
        right: -50%;
        bottom: -50%;
        border: 1px solid #c8c7cc;
        border-radius: 12upx;
        transform: scale(.5)
    }

    .uni-numbox__minus,
    .uni-numbox__plus {
        margin: 0;
        background-color: #f8f8f8;
        width: 70upx;
        font-size: 40upx;
        height: 100%;
        line-height: 70upx;
        text-align: center;
        color: #333;
        position: relative
    }

    .uni-numbox__value {
        position: relative;
        background-color: #fff;
        width: 80upx;
        height: 100%;
        line-height: 70upx;
        text-align: center;
        padding: 0;
        /* 解决app端输入框高度超出问题 */
        min-height: 1.2rem;
    }
    /* 解决app端输入框高度超出问题(未实现) */
    /* .uni-numbox input{
        height: 100%;
        line-height: 70upx;
    } */
    
    .uni-numbox__value:after {
        content: '';
        position: absolute;
        transform-origin: center;
        box-sizing: border-box;
        pointer-events: none;
        top: -50%;
        left: -50%;
        right: -50%;
        bottom: -50%;
        border-style: solid;
        border-color: #c8c7cc;
        border-left-width: 1px;
        border-right-width: 1px;
        border-top-width: 0;
        border-bottom-width: 0;
        transform: scale(.5)
    }

    .uni-numbox--disabled {
        color: silver
    }
</style>
<template>
    <view class="uni-numbox">
        <view class="uni-numbox__minus" :class="{'uni-numbox--disabled': disableSubtract||disabled}" @click="_calcValue('subtract')">-</view>
        <input class="uni-numbox__value" type="number" :disabled="disabled" :value="inputValue" @blur="_onBlur">
        <view class="uni-numbox__plus" :class="{'uni-numbox--disabled': disableAdd||disabled}" @click="_calcValue('add')">+</view>
    </view>
</template>
<script>
    export default {
        name: 'uni-number-box',
        props: {
            value: {
                type: Number,
                default: 1
            },
            min: {
                type: Number,
                default: 0
            },
            max: {
                type: Number,
                default: 100
            },
            step: {
                type: Number,
                default: 1
            },
            disabled: {
                type: Boolean,
                default: false
            },
            // 新增属性
            cid: {
                type: String,
                default: ""
            }
        },
        data() {
            return {
                inputValue: this.value
            }
        },
        computed: {
            disableSubtract() {
                return this.inputValue <= this.min
            },
            disableAdd() {
                return this.inputValue >= this.max
            }
        },
        watch: {
            value(val) {
                this.inputValue = val;
            },
            inputValue(val) {
                // this.$emit('change', val);
                this.$emit('change', {value: val, cid: this.cid});
            }
        },
        methods: {
            _calcValue(type) {
                if (this.disabled) {
                    return
                }
                const scale = this._getDecimalScale()
                let value = this.inputValue * scale
                let step = this.step * scale
                if (type === 'subtract') {
                    value -= step
                } else if (type === 'add') {
                    value += step
                }
                if (value < this.min || value > this.max) {
                    return
                }
                this.inputValue = value / scale;
            },
            _getDecimalScale() {
                let scale = 1
                // 浮点型
                if (~~this.step !== this.step) {
                    scale = Math.pow(10, (this.step + '').split('.')[1].length)
                }
                return scale
            },
            _onBlur(event) {
                let value = event.detail.value
                if (!value) {
                    this.inputValue = 0
                    return
                }
                value = +value;
                if (value > this.max) {
                    value = this.max
                } else if (value < this.min) {
                    value = this.min
                }
                this.inputValue = value
            }
        }
    }
</script>
<style>
    @charset "UTF-8";

    .uni-numbox {
        display: inline-flex;
        flex-direction: row;
        justify-content: flex-start;
        height: 70upx;
        position: relative
    }

    .uni-numbox:after {
        content: '';
        position: absolute;
        transform-origin: center;
        box-sizing: border-box;
        pointer-events: none;
        top: -50%;
        left: -50%;
        right: -50%;
        bottom: -50%;
        border: 1px solid #c8c7cc;
        border-radius: 12upx;
        transform: scale(.5)
    }

    .uni-numbox__minus,
    .uni-numbox__plus {
        margin: 0;
        background-color: #f8f8f8;
        width: 70upx;
        font-size: 40upx;
        height: 100%;
        line-height: 70upx;
        text-align: center;
        color: #333;
        position: relative
    }

    .uni-numbox__value {
        position: relative;
        background-color: #fff;
        width: 80upx;
        height: 100%;
        line-height: 70upx;
        text-align: center;
        padding: 0;
        /* 解决app端输入框高度超出问题 */
        min-height: 1.2rem;
    }
    /* 解决app端输入框高度超出问题(未实现) */
    /* .uni-numbox input{
        height: 100%;
        line-height: 70upx;
    } */
    
    .uni-numbox__value:after {
        content: '';
        position: absolute;
        transform-origin: center;
        box-sizing: border-box;
        pointer-events: none;
        top: -50%;
        left: -50%;
        right: -50%;
        bottom: -50%;
        border-style: solid;
        border-color: #c8c7cc;
        border-left-width: 1px;
        border-right-width: 1px;
        border-top-width: 0;
        border-bottom-width: 0;
        transform: scale(.5)
    }

    .uni-numbox--disabled {
        color: silver
    }
</style>

注意:源码修改后单独使用时该拓展组件时需修改相关代码

<view class="uni-flex uni-row align-center jk-des">
    <text>合格件数:</text>
    <uni-number-box :value="qualifiedNumber" @change="changeQualifiedNumber"></uni-number-box>
</view>
data() {
    return {
        qualifiedNumber: 10
    }
},
changeQualifiedNumber:function(value){
    this.qualifiedNumber = value;
},
changeQualifiedNumber:function(event){
    this.qualifiedNumber = event.value;
},

3. 动态设置最大最小值时输入框显示异常且增减按钮触发异常

data() {
    return {
        qualifiedNumber: 10,
        qualifiedMin:0,
        qualifiedMax:10,
    }
},
<view class="uni-flex uni-row align-center jk-des">
    <text>合格件数:</text>
    <uni-number-box :value="qualifiedNumber" :min="qualifiedMin" :max="qualifiedMax" @change="changeQualifiedNumber"></uni-number-box>
</view>
<view class="uni-flex margin-tb-sm jk-des">合格最小值:{{qualifiedMin}},合格最大值:{{qualifiedMax}}</view>
changeQualifiedNumber:function(event){
    this.qualifiedNumber = event.value;
},
modifyNumber:function(){
    var reworkArray = [2,4,1];//此处实际是动态数据
    var reworkMin = Math.max.apply(null, reworkArray);
    var qualifiedMax = _self.styleInfo.num - reworkMin;
    console.log("qualifiedMax:" + qualifiedMax);
    _self.qualifiedMax = qualifiedMax;
    _self.qualifiedNumber = _self.qualifiedMax;
            
    var sum = eval(reworkArray.join("+"));
    var reworkMax = Math.min(sum,_self.styleInfo.num);
    var qualifiedMin = _self.styleInfo.num - reworkMax;
    console.log("qualifiedMin:" + qualifiedMin);
    _self.qualifiedMin = qualifiedMin;
},
效果.png

解决:动态变化最大最小值时,将输入框默认值设置为最大(小)值

modifyNumber:function(){
    var reworkArray = [2,4,1];//此处实际是动态数据
    var reworkMin = Math.max.apply(null, reworkArray);
    var qualifiedMax = _self.styleInfo.num - reworkMin;
    console.log("qualifiedMax:" + qualifiedMax);
    _self.qualifiedMax = qualifiedMax;
    _self.qualifiedNumber = qualifiedMax;//输入框的值设置为范围最大值
            
    var sum = eval(reworkArray.join("+"));
    var reworkMax = Math.min(sum,_self.styleInfo.num);
    var qualifiedMin = _self.styleInfo.num - reworkMax;
    console.log("qualifiedMin:" + qualifiedMin);
    _self.qualifiedMin = qualifiedMin;
},
上一篇下一篇

猜你喜欢

热点阅读