说说如何在Vue.js中实现数字输入组件的方法


Posted in Javascript onJanuary 08, 2019

我们对普通输入框进行扩展,实现一个可快捷输入数字组件。

首先制定规则:

  • 只能输入数字。
  • 设计两个快捷按钮,可直接在当前值的基础上增 1 或者减 1。
  • 数字输入组件可设置初始值、最大值与最小值。

接着,规划好 API。一个 Vue.js 组件最重要的 3 个部分就是 props、events 以及 slot,我们需要定义这三个部分的命名以及业务规则。这个组件比较简单,所以我们只用到  props 与 events。

1 基础版

html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>数字输入组件</title>
</head>
<body>
<div id="app">
  <number-input v-model="value" :min="0" :max="6"></number-input>
</div>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
<script src="number.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      value: 3
    }
  });
</script>
</body>
</html>

这里,我们使用了 v-model,双向绑定了 value。

number.js:

/**
 * 是否为数字
 * @param val
 * @returns {boolean}
 */
function isNum(val) {
  return (/^[0-9]*$/).test(val);
}

/**
 * 数字输入组件
 */
Vue.component('number-input', {
  template: '\
  <div class="number-input">\
    <input \
      type="text"\
      :value="currentVal"\
      @change="change">\
    <button\
      @click="down"\
      :disabled="currentVal<=min">-</button>\
    <button\
      @click="up"\
      :disabled="currentVal >=max">+</button>\
  </div>',
  props: {//校验
    //最大值
    max: {
      type: Number,
      default: Infinity
    },
    //最小值
    min: {
      type: Number,
      default: -Infinity
    },
    //初始值
    value: {
      type: Number,
      default: 0
    }
  },
  data: function () {
    return {
      currentVal: this.value
    }
  },
  watch: {
    currentVal: function (val) {
      console.log("currentVal:" + this.currentVal);
      this.$emit('input',val);
    },
    value: function (val) {//更新 currentVal
      this.update(val);
    }
  },
  methods: {
    /**
     * 更新
     * @param val
     */
    update: function (val) {
      //让输入的值在限定范围内
      if (val > this.max) {
        val = this.max;
      }
      if (val < this.min) {
        val = this.min
      }
      this.currentVal = val;
    },
    /**
     * 减少
     */
    down: function () {
      if (this.currentVal <= this.min) {
        return;
      }
      this.currentVal -= 1;
    },
    /**
     * 增长
     */
    up: function () {
      if (this.currentVal >= this.max) {
        return;
      }
      this.currentVal += 1;
    },
    /**
     * 如果输入的值,
     * @param event
     */
    change: function (event) {
      var val = event.target.value.trim();//获取输入值

      if (isNum(val)) {//赋值 currentVal
        val = Number(val);
        this.currentVal = val;

        //超出限定范围时,规整
        var max = this.max;
        var min = this.min;
        if (val > max) {
          this.currentVal = max;
        } else if (val < min) {
          this.currentVal = min;
        }
      } else {//还原为 currentVal
        event.target.value = this.currentVal;
      }
    }
  },
  mounted: function () {
    //对初始值进行范围限定
    this.update(this.value);
  }
});

这里,我们专门定义了一个 number.js,用于定义数字输入组件。
在 number.js 中,我们做了如下工作:

  1. 利用正则表达式 ,定义了一个判断 “是否为数字” 的函数。
  2. 在模板定义中,我们定义了一个输入框以及两个按钮,首先在 input 中绑定了 currentVal 数据以及原生的 change 事件。接着,定义了递增与递减按钮,每个按钮都绑定了相应的事件,还绑定了 disabled 属性,这样当输入的值超出范围时,按钮就会置灰不可用。
  3. 在定义的 change() 方法中,先获取输入值,然后判断是否为数字。如果是数字,则赋值给 currentVal;如果不是数字,则还原为 currentVal,这样可以保证组件的内容始终是数字。
  4. 接着在 props 中,对每一个参数(最大值、最小值、初始值)定义了相应的校验规则。这样就可以在父组件中初始化这个数字输入组件啦O(∩_∩)O~
  5. 因为 Vue.js 组件时单向数据流,所以不能在组件内部修改之前在 props 中定义的 value。我们可以在 data 函数中,声明一个 currentVal,并把  props 中定义的 value 值赋给它。这样就实现了组件初始化时,引用父组件中的值的工作。
  6. 为了当父组件修改了输入值,也要更新子组件中的 currentVal 的功能,我们需要用到 watch 属性。 watch 属性用于监听某个 prop 或者 data,当它们发生变化时,会触发定义在 watch 中的函数。这里我们监听了 currentVal 与 value,监听了 currentVal 是为了将来当内部更新了 currentVal 的场景时,可以同步到 Value,这里起核心作用的是监听 value 值。为了让输入的值在限定范围内,这里封装了一个 update() 函数。
  7. watch 中的监听函数,有两个入参,第一个是新值,第二个是旧值。这里只用到新值。因为监听函数中的 this ,指向的是当前组件实例,所以可以直接调用定义在 methods 中的函数。
  8. 为了在组件初始化时,对初始值进行范围限定,这里在 mounted 挂载函数中,也调用了 update() 函数。

效果:

说说如何在Vue.js中实现数字输入组件的方法

2 按键支持

当输入框获得焦点时,按下“向上键”时,增长;按下“向上键”时,减少。

这可以利用按键修饰符来实现,我们修改示例中的组件模板:

...
 <input 
      type="text"
      :value="currentVal"
      @change="change"
      @keyup.up="up"
      @keyup.down="down">
...

Vue.js 定义按键别名有这些:

  • .enter
  • .tab
  • .delete(捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

效果:

说说如何在Vue.js中实现数字输入组件的方法

3 控制步伐

新增一个步伐属性,增长或者减少以步伐值为变化量。之前的示例,步伐为 1。

首先在 props 中,定义一个步伐属性:

//步伐
step: {
  type: Number,
  default: 1
}

然后在增长与减少函数中,使用步伐属性做为变化量:

/**
 * 减少
 */
down: function () {
  if (this.currentVal <= this.min) {
    return;
  }
  this.currentVal -= this.step;
},
/**
 * 增长
 */
up: function () {
  if (this.currentVal >= this.max) {
    return;
  }
  this.currentVal += this.step;
},

最后为组件重新配置参数:

<number-input v-model="value" :min="0" :max="50" :step="5"></number-input>

效果:

说说如何在Vue.js中实现数字输入组件的方法

本文示例代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
My Desktop :) 桌面式代码
Dec 29 Javascript
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
Feb 18 Javascript
JavaScript实现点击按钮后变灰避免多次重复提交
Jul 15 Javascript
如何正确使用javascript 来进行我们的程序开发
Jun 23 Javascript
JavaScript利用append添加元素报错的解决方法
Jul 01 Javascript
js实现用户输入的小写字母自动转大写字母的方法
Jan 21 Javascript
JavaScript中Object值合并方法详解
Dec 22 Javascript
JS动画定时器知识总结
Mar 23 Javascript
详解Node.js 中使用 ECDSA 签名遇到的坑
Nov 26 Javascript
微信小程序实现消息框弹出动画
Apr 18 Javascript
JS前后端实现身份证号验证代码解析
Jul 23 Javascript
国庆节到了,利用JS实现一个生成国庆风头像的小工具 详解实现过程
Oct 05 Javascript
小试SVG之新手小白入门教程
Jan 08 #Javascript
vue组件通信传值操作示例
Jan 08 #Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
Jan 08 #Javascript
vuejs简单验证码功能完整示例
Jan 08 #Javascript
详解React中合并单元格的正确写法
Jan 08 #Javascript
JS简单判断是否在微信浏览器打开的方法示例
Jan 08 #Javascript
JQuery搜索框自动补全(模糊匹配)功能实现示例
Jan 08 #jQuery
You might like
php支付宝APP支付功能
2020/07/29 PHP
在JavaScript里嵌入大量字符串常量的实现方法
2013/07/07 Javascript
JS建造者模式基本用法实例分析
2015/06/30 Javascript
详解JavaScript for循环中发送AJAX请求问题
2020/06/23 Javascript
微信小程序 scroll-view实现锚点滑动的示例
2017/12/06 Javascript
vue生成token并保存到本地存储中
2018/07/17 Javascript
Vue-CLI3.x 设置反向代理的方法
2018/12/06 Javascript
微信小程序实现原生步骤条
2019/07/25 Javascript
vue 动态组件用法示例小结
2020/03/06 Javascript
Vue中使用better-scroll实现轮播图组件
2020/03/07 Javascript
vue实现顶部菜单栏
2020/11/08 Javascript
[00:53]TI3正赛第三天 DK怒破A队不败金身 现场国旗飘扬热血激昂
2013/08/10 DOTA
Python的gevent框架的入门教程
2015/04/29 Python
编写Python脚本批量下载DesktopNexus壁纸的教程
2015/05/06 Python
Python找出最小的K个数实例代码
2018/01/04 Python
Selenium定时刷新网页的实现代码
2018/10/31 Python
django+mysql的使用示例
2018/11/23 Python
聊聊python里如何用Borg pattern实现的单例模式
2019/06/06 Python
Python API 自动化实战详解(纯代码)
2019/06/11 Python
Python xlrd excel文件操作代码实例
2020/03/10 Python
Ryderwear美国官网:澳大利亚高端健身训练装备品牌
2018/04/24 全球购物
Lookfantastic澳大利亚官网:英国知名美妆购物网站
2021/01/07 全球购物
编写用C语言实现的求n阶阶乘问题的递归算法
2014/10/21 面试题
在SQL Server中创建数据库主要有那种方式
2013/09/10 面试题
造型师求职自荐信
2013/09/27 职场文书
拾金不昧的表扬信
2014/01/16 职场文书
商场端午节活动方案
2014/01/29 职场文书
机械专业应届毕业生自荐书
2014/06/12 职场文书
基层工作经验证明样本
2014/11/16 职场文书
先进党支部事迹材料
2014/12/24 职场文书
大学生毕业评语
2014/12/31 职场文书
大学生个人学习总结
2015/02/15 职场文书
舌尖上的中国观后感
2015/06/02 职场文书
旷工检讨书大全
2015/08/15 职场文书
大学军训口号大全
2015/12/24 职场文书
如何利用python和DOS获取wifi密码
2021/03/31 Python