vue js的数字输入组件

numeric input component for vue js

这是我使用 Numeral.js:

的实现

        Vue.filter('formatNumber', function (value) {
            return numeral(value).format('0,0.[000]')
        })

        Vue.component('input-number', {
            template: '\
    <div>\
      <label v-if="label">{{ label }}</label>\
      <input\
        ref="input"\
        v-bind:value="displayValue(value)"\
        v-on:input="updateValue($event.target.value)"\
        v-on:focus="selectAll"\
      >\
    </div>\
  ',
            props: {
                value: {
                },
                label: {
                }
            },
            methods: {
                updateValue: function (inputValue) {

                    var valToSend = inputValue

                    var numVal = numeral(valToSend).value()
                    
                    if (isNaN(numVal)) {
                        valToSend = this.value.toString()
                        numVal = numeral(valToSend).value()
                    }

                    var formattedVal = numeral(numVal).format('0,0.[000]')

                    this.$refs.input.value = formattedVal + (valToSend.endsWith('.') ? '.' : '')

                    this.$emit('input', numeral(formattedVal).value())
                    

                },
                displayValue: function (inputValue) {
                    return numeral(inputValue).format('0,0.[000]')
                },
                selectAll: function (event) {
                    // Workaround for Safari bug
                    // 
                    setTimeout(function () {
                        event.target.select()
                    }, 0)
                }
            }
        })
        var app = new Vue({
            el: '#app',
            data: {
                pricePerGram: '160000',
                weightInGrams: '1.5',
            },
            computed: {
                totalPrice: function () {
                    return (this.pricePerGram * this.weightInGrams)
                },
                toatlWithVat: function () {
                    return (this.totalPrice *1.09)
                }
            }
        })
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>

    <div id="app">
        <input-number v-model="pricePerGram" label="Price per gram:"></input-number><br />
        <input-number v-model="weightInGrams" label="Weight in grams:"></input-number><br />
        <div><label>Total price: </label><span dir="ltr">{{totalPrice | formatNumber}}</span></div><br />
        <div><label>Total + Vat: </label><span dir="ltr">{{toatlWithVat | formatNumber}}</span></div><br />
    </div>

我做的对吗?有没有更好的方法来实现纯数字输入?

我希望对此进行改进。使用 Numeral.js 不是强制性的。这只是我找到的一个图书馆。

关于当前实施的一些事情:

这应该有效 (Codepen):

Vue.component("input-number", {
  template: '<input type="string" v-model="model">',

  props: {
    value: {
      type: String,
      required: true,
    }
  },

  computed: {
    model: {
      get() {
        // We extract decimal number, beacause toLocaleString will automagically
        // remove the dot and zeros after it while the user is still typing
        let value = this.value.split(".");
        let decimal = typeof value[1] !== "undefined"
          ? "." + value[1]
          : "";

        return Number(value[0]).toLocaleString("en-GB") + decimal;
      },

      set(newValue) {
        this.$emit("input", newValue.replace(/,/g, ""));
      }
    }
  }
});

new Vue({
  el: "#app",
  data: {
    input: "1234567.890",
  }
});