vue,el-input,如何实现一个货币的输入框,类似excel中的?

需要的效果,类似 excel 中的货币格式输入框

  • 在存在焦点输入的时候,显示为数字
    image.png
  • 失去焦点,显示货币分隔符
    image.png
  • 支持复制粘贴带货币分隔符的数字,并且
    image.png

粘贴的时候去除逗号,失去焦点的时候又显示货币格式
image.png
image.png

阅读 1.3k
avatarAI BotBETA

在 Vue 中使用 Element UI 的 el-input 组件来实现一个类似 Excel 中的货币输入框,需要用到输入框的 v-model 指令和自定义格式器。这里我们使用 Vue.jsElement UI 创建一个简单的应用来展示如何实现这个功能。

首先,你需要在你的 Vue 项目中安装和引入 Element UI。你可以通过 npm 或者 yarn 来安装 Element UI:

npm install element-ui
# 或者
yarn add element-ui

在你的 Vue 文件中引入 Element UI 和相应的样式文件:

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

然后,你可以在你的 Vue 模板中创建一个 el-input 组件,并使用 v-model 指令绑定到数据对象的属性上。为了实现货币格式,我们需要用到 el-input:formatter 属性,它可以接受一个函数,这个函数接收一个参数,就是用户输入的内容,我们要在这个函数里对输入的内容进行处理:

<template>
  <el-input
    v-model="input"
    :formatter="formatInput"
    placeholder="请输入货币数值"
  ></el-input>
</template>

在你的 Vue 实例中定义 input 数据属性和 formatInput 方法:

export default {
  data() {
    return {
      input: ''
    }
  },
  methods: {
    formatInput(value) {
      if (value) {
        // 当输入框有值的时候,显示为数字
        return value;
      } else {
        // 当失去焦点或者输入逗号时,显示货币格式
        return this.input.replace(/[^\d]/g, '').replace(/(\d)(?=(\d{3})+$)/g, '$1,');
      }
    }
  }
}

在这个例子中,当输入框里有值的时候,就显示为数字。当输入框失去焦点或者输入逗号时,就显示为货币格式。注意这里我们使用了 JavaScript 的 replace 方法来替换字符串中的字符,实现货币格式的显示。例如,/[^\d]/g 匹配所有非数字字符,然后用空字符串替换它们;/(\d)(?=(\d{3})+$)/g 匹配每三位数字后面加一个逗号,例如把 "1234567" 变为 "1,234,567"。

3 个回答

刚好我也是做在线表格的
你说的这种格式我之前也做过 不过是 canvas 实现的。
我简单给你说下思路吧。

const inputConfig = {
  //  input 文本
  value: '99633311',
  /**
   * 这种我就参照 excel 的 format 给你定义
   * format定义规则 url: https://customformats.com/
   */
  format: '#,##0'
};

const input = document.createElement('input');

//  聚焦 99,633,311 => 99633311
input.onfocus = () => {
  inputConfig.value.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

// 失焦 99633311 = > 99,633,311
input.onblur = () => {
  inputConfig.value.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

input.onchange = (e: any) => {
  inputConfig.value = e.target.value;
}

/**
 * 复制粘贴也是一样  format 一下 value 值
 * @param e 
 */

input.oncopy = (e: any) => {
  e.clipboardData.setData('text/plain', inputConfig.value);
  e.preventDefault();
};

input.onpaste = (e: any) => {
 
}

可以通过设置formatter来修改格式化文字,当获取焦点的时候不格式化,原样输出,失去焦点的时候再格式化,需要思考的是怎么让他更新,我这里是加了个nextTick给他重新赋值让他更新,你可以思考下有没有别的比较好的方法

image.png

我也提供一个思路吧,失焦聚焦时直接修改dom即可
DEMO

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏