vue自定义一个指令实现el-input-number组件显示千分号,但实际拿到的值是number类型

news/2024/7/7 5:55:10 标签: vue.js, javascript, 前端

下面先简单实现聚焦输入时是数字,失焦时展示千分号,但实际拿到的值也还是数字;

<el-input-number v-model="form.aaaa" :min="0" :precision="2" v-thousands>
</el-input-number>
directives: {
  thousands: {
    // 被绑定元素插入父节点时调用
    inserted: function (el) {
      // 获取input节点
      if (el.tagName.toLocaleUpperCase() !== 'INPUT') {
        el = el.getElementsByTagName('input')[0]
      }
      // 千分位
      el.value = parseFloat(el.value).toLocaleString('zh', {
      	minimumFractionDigits: 2,
        maximumFractionDigits: 2
      })
      // 聚焦转化为数字格式(去除千分位)
      el.onfocus = e => {
        let a = el.value.replace(/,/g, '') //去除千分号的','
        el.value = parseFloat(a).toFixed(2)
      }
      el.onblur = e => {
        el.value = parseFloat(el.value).toLocaleString('zh', {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      }
    }
  }
}

以上的例子可以实现把el-input-number绑定的初始值转化成千分号,也可以在失焦时转化千分号;
但是如果是通过调用接口获取数据,再赋值给el-input-number绑定的值,就不能实现页面刚加载就展示千分号;原因是因为inserted只在插入父节点时调用,只会执行一次,也就是在初始化页面的时候会调用一次,当数据更新后不会再调用,因此不能实现在数据更新后,转化为千分号;

改变思路:使用update代替inserted,update是组件VNode更新时调用,当数据发生变化的时候,VNode必然会更新;

directives: {
  thousands: {
    // 虚拟dom更新时调用
    update: function (el) {
    console.log("执行了吗")  // 执行两次
      // 获取input节点
      if (el.tagName.toLocaleUpperCase() !== 'INPUT') {
        el = el.getElementsByTagName('input')[0]
      }
      // 千分位
      el.value = parseFloat(el.value).toLocaleString('zh', {
      	minimumFractionDigits: 2,
        maximumFractionDigits: 2
      })
      // 聚焦转化为数字格式(去除千分位)
      el.onfocus = e => {
        let a = el.value.replace(/,/g, '') //去除千分号的','
        el.value = parseFloat(a).toFixed(2)
      }
      el.onblur = e => {
        el.value = parseFloat(el.value).toLocaleString('zh', {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      }
    }
  }
}

以上的例子实现了在虚拟dom更新时也会执行,但是还是不能实现接口数据返回后执行,因为ajax请求是属于异步操作,update钩子函数中拿不到数据更新后的值,思路是使用setTimeout转化成异步,就可以拿到了

let timer = setTimeout(() => {
  console.log("最新的值",el.value)
  // 千分位
  el.value = parseFloat(el.value).toLocaleString('zh', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  })
  clearTimeout(timer)
}, 0)

完整代码:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>

<style>
  .el-input-number {
    width: 200px;
  }

  .el-input-number>.el-input-number__decrease {
    display: none;
  }

  .el-input-number>.el-input-number__increase {
    display: none;
  }

  .el-input__inner {
    padding-left: 10px !important;
    padding-right: 0px !important;
    text-align: left !important;
  }

  #app {
    margin: 300px auto;
  }

  #app>div {
    text-align: center;
  }

  #app>div:nth-child(1) {
    margin-bottom: 10px;
  }

  /* [v-clock] {
    display: none;
  } */
</style>

<body>
  <div id="app">
    <div>
      <el-button type="primary" @click="getShow">{{!show?'显示':'隐藏'}}</el-button>
    </div>
    <div>
      <el-input-number v-model="form.aaaa" :min="0" :precision="2" v-thousands v-if="show">
      </el-input-number>
      <el-input-number v-model="form.bbbb" :min="0" :precision="2" v-thousands v-if="show" disabled>
      </el-input-number>
    </div>
  </div>
</body>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>javascript">
  new Vue({
    el: '#app',
    data: function () {
      return {
        form: {
          aaaa: null,
          bbbb: null
        },
        show: false,
        timer: null
      }
    },
    methods: {
      // 显示input
      getShow() {
        this.show = !this.show
        if (this.show) {
          this.getData()
        } else {
          this.clearData()
        }
      },
      // 模拟调用接口
      getData() {
        setTimeout(() => {
          this.form.aaaa = 2300.05
          this.form.bbbb = 18540022.89
        }, 500)
      },
      // 清空数据
      clearData() {
        this.form.aaaa = null
        this.form.bbbb = null
      }
    },
    directives: {
      thousands: {
        // 被绑定元素插入父节点时调用
        update: function (el, binding, vnode, oldVnode) {
          // 获取input节点
          if (el.tagName.toLocaleUpperCase() !== 'INPUT') {
            el = el.getElementsByTagName('input')[0]
          }
          // 转化成异步,否则无法拿到更新后的el.value的值
          let timer = setTimeout(() => {
            let a = el.value.replace(/,/g, '') //去除千分号的','
            el.value = parseFloat(a).toFixed(2)
            el.value = parseFloat(el.value).toLocaleString('zh', {
              minimumFractionDigits: 2,
              maximumFractionDigits: 2
            })
            clearTimeout(timer)
          }, 0)
          // 聚焦转化为数字格式(去除千分位)
          el.onfocus = e => {
            let a = el.value.replace(/,/g, '') //去除千分号的','
            el.value = parseFloat(a).toFixed(2)
          }
          el.onblur = e => {
            el.value = parseFloat(el.value).toLocaleString('zh', {
              minimumFractionDigits: 2,
              maximumFractionDigits: 2
            })
          }
        }
      }
    }
  })
</script>

</html>

http://www.niftyadmin.cn/n/10360.html

相关文章

多进程编程

系列文章目录 多进程编程 VS 多线程编程_crazy_xieyi的博客-CSDN博客 文章目录 前言一、进程创建二、进程等待前言 Java对操作系统提供的多进程编程接口这些操作进行了限制&#xff0c;最终给用户只提供了两个操作&#xff1a;进程创建和进程等待。 一、进程创建 创建出一个…

postgres-operator 原理解析- 章节 II 减少failover次数

本文讨论一波&#xff0c;kubernetes集群部署的高可用postgresql集群在滚动更新场景下&#xff0c;如何实现减少failover次数&#xff1f; 这个原理我觉得适用于任何主从架构的中间件&#xff0c;是一个通用的设计技巧。 那就是&#xff1a; 在进行滚动升级过程中&#xff0c…

数商云S2B2C商城积分商城功能如何实现家用电器企业营销价值最大化?

随着数字化商业时代的到来&#xff0c;消费者行为发生了深刻变化&#xff0c;多元化的消费需求不断驱动着品牌营销思维的变革。对于家用电器行业来说&#xff0c;如何顺应消费者的消费行为变化&#xff0c;不断完善整合更新用户需求&#xff0c;应用更智能化的营销手段与消费者…

Python Selenium unittest+HTMLTestRunner实现 自动化测试及发送测试报告邮件

1、UI测试框架搭建-目录结构 2、 文件介绍 2.1、baseinfo->__init__.py 配置文件定义基础参数 #-*-coding:utf-8-*- #测试用例配置参数base_url "http://xxxxx.com" undirect_username "username" undirect_password "password" direct_…

Numpy字符串数组总结

文章目录字符串函数列表函数说明numpy中的 char模块中&#xff0c;封装了一些处理字符串数组的函数字符串函数列表 类别方法创建array, asarray, chararray运算add, multiply填充center, ljust, rjust, zfill大小写转换lower, upper, capitalize, title, swapcase去除lstrip, …

STM32 CRC计算单元(循环冗余校验)

STM32第三篇【1】STM32 CRC计算单元【2】STM32 CRC简介【3】STM32 CRC主要特性【4】STM32 CRC功能描述【5】STM32 CRC寄存器【6】STM32 数据寄存器&#xff08;CRC_DR&#xff09;【7】STM32 独立数据寄存器&#xff08;CRC_IDR&#xff09;【8】STM32 控制寄存器&#xff08;C…

前缀和【一维前缀和与二维前缀和】

全文目录&#x1f600; 一维前缀和&#x1f914; 构建一维前缀和数组&#x1f635;‍&#x1f4ab; 子序列的和&#x1f600; 二维前缀和&#x1f914; 构建二维前缀和数组&#x1f635;‍&#x1f4ab; 子矩阵的和&#x1f600; 一维前缀和 一维前缀和很简单&#xff0c;就是…

【JavaEE】PCB和进程调度的基本过程

文章目录什么是进程PCB的组成PID内存指针文件描述符表并行和并发进程调度相关属性进程的状态优先级上下文进程的记账信息什么是进程 进程是正在运行的程序的实例&#xff08;an instance of a computer program that is being executed&#xff09; 进程&#xff08;process&am…