在Vue.js 2.0中在v-model上实现格式化的正确方法是什么

时间:2016-12-13 02:13:32

标签: vue.js

举个简单的例子:文本框输入货币数据。 要求是以“$ 1,234,567”格式显示用户输入并删除小数点。

我试过了vue指令。由于其他控件刷新UI时,不会调用指令的更新方法。因此,文本框中的值将恢复为没有任何格式的值。

我也试过v-on:更改事件处理程序。但我不知道如何在事件处理程序中调用全局函数。在每个Vue对象中创建货币转换方法不是一个好习惯。

那么现在Vue 2.0中标准的格式化方式是什么?

此致

4 个答案:

答案 0 :(得分:25)

请查看此工作jsFiddle示例:https://jsfiddle.net/mani04/bgzhw68m/

在此示例中,格式化的货币输入本身就是一个组件,它使用v-model,就像Vue.js中的任何其他表单元素一样。您可以按如下方式初始化此组件:

<my-currency-input v-model="price"></my-currency-input>

my-currency-input是一个自包含组件,可在输入框无效时格式化货币值。当用户将光标放入其中时,格式化将被删除,以便用户可以轻松地修改该值。

以下是它的工作原理:

my-currency-input组件的计算值为displayValue,其中定义了getset个方法。在get方法中,如果输入框未激活,则返回格式化的货币值。

当用户在输入框中输入内容时,set计算属性的displayValue方法会使用$emit发出值,从而通知父组件此更改。

在自定义组件上使用v-model的参考:https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events

答案 1 :(得分:7)

以下是一个工作示例:https://jsfiddle.net/mani04/w6oo9b6j/

它的工作原理是在焦点输出和聚焦事件期间修改输入字符串(您的货币值),如下所示:

<input type="text" v-model="formattedCurrencyValue" @blur="focusOut" @focus="focusIn"/>
  1. 当您将光标放在输入框内时,它需要this.currencyValue并将其转换为纯格式,以便用户可以修改它。

  2. 用户键入值并在其他位置单击(焦点偏移)后,忽略非数字字符后重新计算this.currencyValue,并根据需要格式化显示文本。

  3. 货币格式化程序(reg exp)是此处的复制粘贴:How can I format numbers as money in JavaScript?

    如果您不想要提到的小数点,可以使用this.currencyValue.toFixed(0)方法focusOut进行操作。

答案 2 :(得分:0)

我实现了一个组件。根据Mani的回答,它应该使用$ emit。

Vue.component('currency', {
template: '<input type="text"' +
            ' class="form-control"' +
            ' :placeholder="placeholder""' +
            ' :title="title"' +
            ' v-model="formatted" />',
props: ['placeholder', 'title', 'value'],
computed: {
    formatted: {
        get: function () {
            var value = this.value;
            var formatted = currencyFilter(value, "", 0);
            return formatted;
        },
        set: function (newValue) {
            var cleanValue = newValue.replace(",", "");
            var intValue = parseInt(cleanValue, 10);
            this.value = 0;
            this.value = intValue;
        }
    }
}
}

);

答案 3 :(得分:0)

使用Vue自定义指令+ .toLocaleString()也是一个很好的选择。

Vue.directive("currency", {
  bind(el, binding, vnode) {
    el.value = binding.value && Number(binding.value).toLocaleString('en-US', {style: 'currency', currency: !binding.arg ? 'USD' : binding.arg });
    el.onblur = function(e) {
      e.target.value = Number(e.target.value).toLocaleString('en-US', {style: 'currency', currency: !binding.arg ? 'USD' : binding.arg});
    };
    el.onfocus = function(e) {
      e.target.value =
        e.target.value && Number(e.target.value.replace(/[^\d.]/g, ""));
    };
    el.oninput = function(e) {
      vnode.context.$data[binding.expression] = e.target.value;
    };
  }
});

以下是示例链接:https://codepen.io/Mahmoud-Zakaria/pen/YzPvNmO