热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

ElementInputNumber计数器的实现示例

这篇文章主要介绍了ElementInputNumber计数器的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

这篇我们继续研究InputNumber。

基本实现

基本的准备工作过后,开始基本实现。

上测试代码:


上组件代码:



上效果:

这次可以复用Input组件,两边加新增/减少两个按钮,实现加减逻辑。再控制最大值最小值的时候,禁用按钮,基本实现完成。

点击按钮持续增加/减少

现在添加:点击加减按钮的时候,不抬起鼠标,值就会持续增加/减少的特性。

要实现此功能,源码中用到了directive自定义指令,靠节流mousedown事件来实现持续点击效果。

写自定义命令:

import { once, on } from '../utils/dom';

export default {
 bind(el, binding, vnode) {
 let interval = null;
 let startTime;
 // binding.expression 就是decrease/increase 事件名称
 // handler就是对应的相应函数
 const handler = () => vnode.context[binding.expression].apply();
 const clear = () => {
  if (Date.now() - startTime <100) {
  handler();
  }
  clearInterval(interval);
  interval = null;
 };

 on(el, 'mousedown', (e) => {
  if (e.button !== 0) return;
  startTime = Date.now();
  once(document, 'mouseup', clear);
  clearInterval(interval);
  // 实现节流
  interval = setInterval(handler, 100);
 });
 }
};

在组件中使用自定义命令:

import RepeatClick from '../../directives/repeat-click';

directives: {
 repeatClick: RepeatClick
},


 


 

禁用状态

  • 添加 { 'is-disabled': disabled } 到根节点样式上。
  • 添加:disabled="disabled"到el-input节点上。
  • 添加if(this.disabled) return 到decrease/increase方法上。

完成效果:

步数

上测试代码:

给组件添加step属性。在组件中把+/-1这样到代码替换为+/- this.step。

严格步数

step-strictly属性接受一个Boolean。如果这个属性被设置为true,则只能输入步数的倍数。

上测试代码:

 

要想实现严格步数,我们直接输入的值,会检查是不是step的倍数,如果不是,则换成step的倍数。这就不能直接把InputNumber的value直接绑定在内部的el-input上了。先在el-input的input事件记录输入的值。再在change事件中将值赋予给value,最后在watch.value上校验输入的值,并转换成step的倍数。

data() {
 return {
 currentValue: 0, // 缓存上次输入的值
 userInput: null, // 缓存当前输入的值
 };
},




// 先在el-input的input事件记录输入的值
handleInput(value) {
 this.userInput = value;
},
// 在change事件中将值赋予给value
handleInputChange(value) {
 let newVal = value === '' &#63; undefined : Number(value);
 
 if (!isNaN(newVal) || value === '') {
  this.setCurrentValue(newVal);
 }
 this.userInput = null;
},
setCurrentValue(newVal) {
 const oldVal = this.currentValue;

 if (newVal >= this.max) newVal = this.max;
 if (newVal <= this.min) newVal = this.min;
 if (oldVal === newVal) return;
 this.userInput = null;
 this.$emit('input', newVal);
 this.$emit('change', newVal, oldVal);
 this.currentValue = newVal;
},

watch: {
 // 在watch.value上校验输入的值,并转换成step的倍数
 value: {
 immediate: true,
 handler(value) {
  let newVal = value === undefined &#63; value : Number(value);
  
  // 设置严格步数的逻辑
  if (this.stepStrictly) {
   newVal = Math.round(newVal / this.step) * this.step
  }

  if (newVal >= this.max) newVal = this.max;
  if (newVal <= this.min) newVal = this.min;

  this.currentValue = newVal;
  this.userInput = null;
  this.$emit('input', newVal);
 }
 }
},

精度

上测试代码:

这里step变成小数了,那在累加得过程中,就会有0.1+0.2这样得精度问题出现了。element的解决思路是将值扩大精度倍进行计算,得到结果后再除以精度倍数。

increase() {
 if(this.maxDisabled || this.disabled) return
 const value = this.value || 0;
 const newVal = this._increase(value, this.step);

 this.setCurrentValue(newVal);
},
_increase(val, step) {
 if (typeof val !== 'number' && val !== undefined) return this.currentValue;
 // step是0.1,precisionFactor是10。
 const precisiOnFactor= Math.pow(10, this.numPrecision);

 return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor);
},

// 确保计算得结果0.10000000001这种误差情况会被消除
 toPrecision(num, precision) {
 if (precision === undefined) precision = this.numPrecision;
 return parseFloat(Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision));
},

在展示的时候,利用toFixed函数展示精度即可。

效果如下:

尺寸

添加size属性,在根元素得样式添加size &#63; 'el-input-number--' + size : ''。

效果如下:

按钮位置

设置 controls-position 属性可以控制按钮位置。

上测试代码:


通过controls-position='right',在组件内控制样式即可。

效果如下:

总结

严格步数和精度这两个特性得逻辑稍有些复杂,需要多研究一会。

源码在码云: https://gitee.com/DaBuChen/my-element-ui/tree/input-number

到此这篇关于Element InputNumber 计数器的实现示例的文章就介绍到这了,更多相关Element InputNumber 计数器内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 项目展示——微微博
    项目展示——微微博微微博,一个强大的新浪微博的Android客户端,采用TX的微信界面来开发Sina的微博客户端大四上学期参加比赛和孟丹一起做的 ... [详细]
  • 本文详细探讨了在Python开发中遇到的ImportError: 无法找到名为Crypto.Cipher的模块的问题,并提供了多种解决方案,包括环境配置、库安装和代码调整等方法。 ... [详细]
  • 教程:如何打造令人印象深刻的GitHub个人主页Readme
    本文将指导您如何创建一个既专业又个性化的GitHub个人主页Readme,通过添加统计数据、常用语言和最近活动等元素,让您的主页更加吸引人。 ... [详细]
  • ANSI最全介绍linux终端字体改变颜色等ANSI转义序列维基百科,自由的百科全书由于国内不能访问wiki而且国内关于ANSI的介绍都是简短的不能达到,不够完整所以转wiki到此 ... [详细]
  • 本文探讨了Thrift作为一款支持多语言的服务开发框架,其在体积、功能、扩展性以及多协议支持等方面的显著优势。特别地,Thrift作为一种RPC(远程过程调用协议)框架,非常适合用于构建可扩展且低耦合的分布式服务系统。文章通过多种编程语言对Thrift服务进行了性能测试,并提供了详细的测试结果。 ... [详细]
  • 开发日志:Git连接异常处理
    记录了一次多台开发机(Windows与MacOS)同时出现GitHub SSH连接超时及权限拒绝的问题,并详细描述了解决过程及最终解决方案。 ... [详细]
  • 深入理解SAP Fiori及其核心概念
    本文详细介绍了SAP Fiori的基本概念、发展历程、核心特性、应用类型、运行环境以及开发工具等,旨在帮助读者全面了解SAP Fiori的技术框架和应用场景。 ... [详细]
  • 本文总结了在使用React Native开发过程中遇到的一些常见问题及其解决方法,包括配置错误、依赖问题和特定组件的使用技巧。 ... [详细]
  • Python安全实践:Web安全与SQL注入防御
    本文旨在介绍Web安全的基础知识,特别是如何使用Python和相关工具来识别和防止SQL注入攻击。通过实际案例分析,帮助读者理解SQL注入的危害,并掌握有效的防御策略。 ... [详细]
  • Web3隐私协议Manta Network与区块链互操作性平台Axelar达成战略合作,共同推进跨链资产的隐私保护。 ... [详细]
  • 本文详细介绍了如何利用go-zero框架从需求分析到最终部署至Kubernetes的全过程,特别聚焦于微服务架构中的网关设计与实现。项目采用了go-zero及其生态组件,涵盖了从API设计到RPC调用,再到生产环境下的监控与维护等多方面内容。 ... [详细]
  • 深入解析 Git 代码提交流程及常见问题处理
    本文详细阐述了使用 Git 进行代码提交的具体步骤,并提供了遇到常见问题时的解决方案,旨在帮助开发者更加高效地管理代码。 ... [详细]
  • 本文介绍了如何使用 Git 命令来忽略那些已经提交或者从远程仓库拉取但在本地进行了修改的文件,避免这些文件在不必要的时候被再次提交。 ... [详细]
  • Python与MySQL交互指南:从基础到进阶
    本文深入探讨了Python与MySQL数据库的集成方法,包括数据库连接、数据表创建、索引管理、数据操作以及如何防止SQL注入等关键内容。适合初学者及希望提升数据库操作技能的开发者。 ... [详细]
  • 本文详细介绍了`org.kie.workbench.common.stunner.bpmn.definition.UserTask.getGeneral()`方法的使用场景和具体实现,并提供了多个实际代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
author-avatar
UUUUUUUUUU8
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有