• 支持千分符的自定义组件input


      1、组件的实现逻辑代码

      暂且将文件名称为thousand-bit-input.vue

    <template>
        <div>
            <input :class="thousandBitInputClass"
                :disabled="disabled"
                :placeholder="placeholder"
                :required="innerRquried"
                :type="type"
                :aria-label="label"
                :value="value" 
                @input="$emit('input', $event.target.value)"
                @change="$emit('change', $event)"
                @blur="blur">
            <div class="commafy-div__error" v-if="showError">{{ errorTip }}</div>
            <div class="commafy-div__error" v-else-if="showRequired">{{ requiredTip }}</div>
        </div>
    </template>
    
    <script>
    import Vue from 'vue'
    export default {
        name: 'thousand-bit-input',
        model: {
            prop: 'value',
            event: 'input'
        },
        props: {
            value: {
                type: [String, Number]
            },
            type: {
                type: String,
                default: 'text'
            },
            label: {
                type: String,
                default: ''
            },
            disabled: {
                type: Boolean,
                default: false
            },
            placeholder: {
                type: String,
                default: ''
            },
            required: {
                type: Boolean,
                default: false
            },
            requiredTip: {
                type: String,
                default: ''
            }
        },
        data() { 
            return {
                errorTip: '请输入数字值,最多保留两位小数',
                showError: false,
                showRequired: false,
                innerRquried: this.required
            }
        },
        computed: {
            thousandBitInputClass: function() {
                let self = this
                let inputClass = {'thousand-bit-input__inner': true}
                if (self.required) {
                    if (self.value) {
                        inputClass['thousand-bit-input__inner_error'] = self.showError
                        self.innerRquried = false
                        self.showRequired = false
                    } else {
                        self.innerRquried = true
                        self.showError = false
                        self.showRequired = true
                    }
                } else {
                    self.innerRquried = false
                    inputClass['thousand-bit-input__inner_error'] = self.showError
                }
                return inputClass
            }
        },
        watch: {
            required: {
                handler: function(newVal, oldVal) {
                    this.innerRquried = newVal
                    this.showRequired = newVal
                },
                immediate: true
            },
            value: {
                handler: function(newVal, oldVal) {
                    if (newVal) {
                        let numberPattern = /^((?:-?0)|(?:-?[1-9]d*))(?:.d{1,2})?$/
                        let numberThousandsPattern = /^((?:-?0)|(?:-?[1-9]d*)|(?:-?[1-9],d{3})?)(?:,d{3})*(?:.d{1,2})?$/
                        let testNumber = value => {
                            if (numberPattern.test(value)) {
                                this.showError = false
                            } else {
                                this.showError = true
                            }
                        }
                        newVal = newVal + ''
                        let index = newVal.indexOf(',')
                        if (index === -1) {
                            testNumber(newVal)
                        } else {
                            if (numberThousandsPattern.test(newVal)) {
                                this.showError = false
                            } else {
                                index = newVal.lastIndexOf(',')
                                if (index === newVal.length - 1) {
                                    this.showError = true
                                }
                                newVal = newVal.replace(/,/g, '')
                                testNumber(newVal)
                            }
                        }
                    } else {
                        this.showError = false
                    }
                    if (this.showError === false && newVal) {
                        let num = newVal + ''
                        if (num.trim() === '') {
                            return ''
                        }
                        let index = num.indexOf('.')
                        let intPart = ''
                        let floatPart = ''
                        if (index !== -1) {
                            intPart = num.substr(0, index)
                            floatPart = num.substr(index)
                        } else {
                            intPart = num
                        }
                        intPart = intPart.replace(/,/g, '')
                        let intPartReverse = intPart.split('').reverse()
                        let length = intPartReverse.length
                        let formatNumber = ''
                        for (let i = 0; i < length; i++) {
                            formatNumber += intPartReverse[i] + ((i + 1) % 3 === 0 && (i + 1) !== length ? ',' : '')
                        }
                        let formatNumber = formatNumber.split('').reverse().join('') + floatPart
                        formatNumber = formatNumber.replace(/^-,/, '-')
                        this.$emit('input', formatValue)
                    }
                },
                immediate: true
            }
        },
        methods: {
            blur(event) {
                let value = this.value
                value = this.$global.Number.toFixedTwo(value)
                this.$emit('input', value)
                this.$emit('blur', event)
            }
        }
    }
    </script>
    
    <style scoped>
    .thousand-bit-input__inner {
        background-color: #fff;
        background-image: none;
        border-radius: 4px;
        border: 1px solid #dcdfe6;
        box-sizing: border-box;
        color: #606266;
        display: inline-block;
        height: 32px;
        line-height: 32px;
        padding: 0 15px;
        transition: border-color .2s cubic-bezier(.645,.045,.355,1);
         100%;
    }
    .thousand-bit-input__inner:hover {
        border-color: #c0c4cc;
    }
    .thousand-bit-input__inner:focus {
        border-color: #409EFF;
    }
    .thousand-bit-input__inner:required,
    .thousand-bit-input__inner_error,
    .thousand-bit-input__inner_error:hover,
    .thousand-bit-input__inner_error:focus {
        border-color: #f56c6c;
    }
    .thousand-bit-input__inner:disabled {
        background-color: #f5f7fa;
        border-color: #e4e7ed;
        color: #c0c4cc;
        cursor: not-allowed;
    }
    input::-webkit-input-placeholder {
        color: #c0c4cc;
    }
    input::-moz-input-placeholder {
        color: #c0c4cc;
    }
    input::-ms-input-placeholder {
        color: #c0c4cc;
    }
    .commafy-div__error {
        color: #f56c6c;
        font-size: 12px;
        line-height: 1;
        position: absolute;
        top: 100%;
        left: 0;
    }
    </style>

      2、组件的使用

    • 在main.js文件中注册为全局组件:
    import thousandBitInput from 'thousand-bit-input'
    
    Vue.component('thousand-bit-input', thousandBitInput)
    • 在需要的文件中使用该组件:
    <thousand-bit-input v-model="name" :disabled="disabled" :required="requried"
       :placeholder="请输入名称"></thousand-bit-input>

       3、说明

      该组件可以直接在项目工程中使用,并且是实时动态转换的。

  • 相关阅读:
    oracle系列--第五篇 PLSQL连接本地的Oracle数据库
    oracle系列--第四篇 Oracle的卸载
    oracle系列--第三篇 Oracle的安装
    oracle系列--第二篇 oracle下载
    WinForm多语言版本实战项目演练
    从C#垃圾回收(GC)机制中挖掘性能优化方案
    jvm内存模型和垃圾回收
    servlet匹配路径时/和/*的区别(转)
    十大经典排序算法(动图演示)(转)
    排序算法
  • 原文地址:https://www.cnblogs.com/bien94/p/12693474.html
Copyright © 2020-2023  润新知