Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

TIP 👉 Reading has spring deep, an inch of time an inch of gold. —– Oh Jeong-baek, “White Deer Cave 2 · 1”

preface

In our daily project development, we often encounter some input box operations. For example, we often deal with money, so we encapsulate the components of this amount input box.

The amount input box component

  • If the value is 128000, 128,000.00 is displayed

attribute

1. Value Value
  • The value is of a numeric type
2. Decimal part number
  • The value is of a numeric type

  • Default value: 2

3. Whether canRound is allowed to be rounded
  • The value is a Boolean type

  • Default value: false

Due to the accuracy of JS’s tofixed method rounding, it is not recommended to set it to true

4. CanNegative Indicates whether negative numbers can be entered
  • The value is a Boolean type

  • Default value: true

5. SuffixText Indicates the text suffix displayed in the input box
  • The value is string

  • Default: “”

6. Icon Input box suffix display icon (suffixText is valid if suffixText is empty)
  • The value is a Boolean or a string (by which the name of the icon is specified)

  • Default value: “RMB”

7. Whether disabled is unavailable
  • The value is a Boolean type
8. Readonly whether to readonly
  • The value is a Boolean type

The event

1. Change Indicates that the value changes
  • Parameter: value Specifies the value entered (value is a value type).

The sample


<template>
    <MoneyInput v-model="moneyValue" @change="handleChange" ></MoneyInput>
</template>

<script>
import MoneyInput from '@/components/pc/moneyInput'

export default {
    name: 'CheckboxDemo'.components: {
        MoneyInput
    },
    data () {
        return {
            moneyValue: 128000}},methods: {
        handleChange (val) {
            console.log('The amount entered is:', val)
        }
    }
}
</script>
Copy the code

Implement MoneyInput. Vue

<template>
    <div class="money-input-wrap" :class="{'show-icon': icon}">
        <template v-if="readonly">
            <span>{{ currentValue | money(currentDecimal) }}</span>
        </template>
        <template v-else>
            <div class="money-input">
                <input ref="rawInput" class="money-raw-input"
                v-model="currentValue"
                @change="handleChange($event)"
                maxlength="15"
                :disabled="disabled"
                :data-canRound="canRound"
                :data-canNegative="canNegative">
                <div class="money-show" :class="disabled ? 'disabled-input' : ''">{{currentValue | money(currentDecimal)}}</div>
            </div>
            <div v-if="suffixText || icon" class="money-suffix-wrap">
                <span v-if="suffixText" class="money-suffix-text">{{suffixText}}</span>
                <Icon v-else class="money-icon" :name="iconName"></Icon>
            </div>
        </template>
    </div>
</template>

<script>
export default {
name: 'MoneyInput'.props: {
    / / the current value
    value: Number.// The number of decimal parts
    decimal: {
        type: Number.default: 2
    },
    // Whether to round
    canRound: {
        type: Boolean.default: false
    },
    // Whether negative numbers are allowed
    canNegative: {
        type: Boolean.default: true
    },
    // postfix text
    suffixText: {
        type: String
    },

    // Whether to display ICONS
    icon: {
        type: [Boolean.String].default: 'rmb'
    },

    // Whether it is available
    disabled: {
        type: Boolean.default: false
    },

    // Whether it is read-only
    readonly: {
        type: Boolean.default: false
    }
},
data () {
    return {
        currentValue: this.value,
        currentDecimal: this.decimal
    }
},
computed: {
    iconName () {
        if (typeof this.icon === 'string') {
            return this.icon
        }
        return 'rmb'}},watch: {
    value (val) {
        this.currentValue = val
    }
},

methods: {
    handleChange (event) {
        let val = event.target.value
        let numVal = Number(val)
        if (val === ' ' || isNaN(numVal)) {
            this.currentValue = null
            this.$emit('input'.null)
            this.$emit('change'.null)}else {
            if (!this.canNegative && numVal < 0) { // Negative numbers are not allowed
                numVal = Math.abs(numVal)
            }
            if (!this.canRound) { // Rounding is not allowed
                let numArray = numVal.toString().split('. ')
                let intStr = numArray[0] // Integer part string

                let decimalStr = numArray.length >= 2 ? numArray[1] : 1 // The decimal part of the string
                if (decimalStr.length > this.decimal) {
                    let newValueStr = intStr + '. ' + decimalStr.substr(0.this.decimal)
                    numVal = Number(newValueStr)
                }
                } else {
                    numVal = this.fixDecimal(numVal, this.decimal) // Correct the decimal number
                }
                this.currentValue = numVal
                this.$emit('input', numVal)
                this.$emit('change', numVal)
            }
        },
        // Correct the decimal number
        fixDecimal (num, decimal) {
            let number = parseFloat(num)
            if(num ! = =undefined&& num ! = =null&& num ! = =' '&&!isNaN(number)) {
                return parseFloat(number.toFixed(decimal))
            }
            return num
        }
    }
}

</script>

<style lang="scss" scoped px2rem="false">$icon-width: 24px; .money-input-wrap { display: table; width: 100%; height: $form-item-height; .money-input { display: table-cell; position: relative; width: 100%; .money-raw-input { position: absolute; top: 0; width: 100%; border: 1px solid $border-color-base; vertical-align: middle; border-radius: 4px; font-size: 14px; color: $input-font-color; opacity: 0; z-index: 1; &:disabled { background-color: $input-disabled-bg-color; cursor: not-allowed; } &:focus { @include primary-border-color(); opacity: 1; &+input.money-show { opacity: 0; } } } .money-show { position: absolute; top: 0; width: 100%; height: $form-item-height; line-height: $form-item-height - 2px; vertical-align: middle; padding: 0 5px; overflow: hidden; color: $color-text-regular; background-color: #FFF; border: 1px solid $border-color-base; border-radius: 4px; &.disabled-input { background-color: $input-disabled-bg-color; cursor: not-allowed; } } } .money-suffix-wrap { display: table-cell; min-width: 24px; padding: 0 5px; height: $form-item-height; vertical-align: middle; text-align: center; color: $color-text-placeholder; background-color: $bg-color-base; border: solid 1px $border-color-base; border-left: 0; border-radius: 0 4px 4px 0; .money-suffix-text { word-break: keep-all; white-space:nowrap; } } &.show-icon { .money-raw-input, .money-show { padding-right: 0; border-radius: 4px 0 0 4px; }}}</style>
Copy the code

index.js

/** * Amount input box *@author qinglianshizhe
* @date 2021/10/11 * /
import MoneyInput from './MoneyInput.vue'
export default MoneyInput

Copy the code

Thanks for the comment section.

Hope to finish watching friends can give a thumbs-up, encourage once