说说如何在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 相关文章推荐
基于jquery实现控制经纬度显示地图与卫星
May 20 Javascript
jquery弹出框的用法示例(2)
Aug 26 Javascript
jQuery获取节点和子节点文本的方法
Jul 22 Javascript
基于javascript、ajax、memcache和PHP实现的简易在线聊天室
Feb 03 Javascript
JavaScript中原型和原型链详解
Feb 11 Javascript
微信小程序 navigation API实例详解
Oct 02 Javascript
vue2.0的contextmenu右键弹出菜单的实例代码
Jul 24 Javascript
vue.js层叠轮播效果的实例代码
Nov 08 Javascript
VUE2.0+ElementUI2.0表格el-table实现表头扩展el-tooltip
Nov 30 Javascript
babel7.x和webpack4.x配置vue项目的方法步骤
May 12 Javascript
angularjs模态框的使用代码实例
Dec 20 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
Aug 25 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获取谷歌PR值算法,附上php查询PR值代码示例
2011/12/25 PHP
Symfony2创建基于域名的路由相关示例
2016/11/14 PHP
详解PHP序列化和反序列化原理
2018/01/15 PHP
jquery text()要注意啦
2009/10/30 Javascript
JavaScript学习历程和心得小结
2010/08/16 Javascript
Jquery弹出窗口插件 LeanModal的使用方法
2012/03/10 Javascript
jQuery实现图片放大预览实现原理及代码
2013/09/12 Javascript
Jquery获得控件值的三种方法总结
2014/02/13 Javascript
JavaScript对IE操作的经典代码(推荐)
2014/03/10 Javascript
jquery解析xml字符串示例分享
2014/03/25 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
2014/09/01 Javascript
node.js中的path.dirname方法使用说明
2014/12/09 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
正则表达式,替换所有HTML标签的简单实例
2016/11/28 Javascript
JavaScript实现鼠标滚轮控制页面图片切换功能示例
2017/10/14 Javascript
vue自定义过滤器创建和使用方法详解
2017/11/06 Javascript
js判断传入时间和当前时间大小实例(超简单)
2018/01/11 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
2018/09/30 Javascript
python网络编程学习笔记(一)
2014/06/09 Python
python 内置函数filter
2017/06/01 Python
python编写微信远程控制电脑的程序
2018/01/05 Python
Python基于socket实现简单的即时通讯功能示例
2018/01/16 Python
python实现机器人行走效果
2018/01/29 Python
PyQt4实时显示文本内容GUI的示例
2019/06/14 Python
python 调试冷知识(小结)
2019/11/11 Python
python em算法的实现
2020/10/03 Python
使用BeautifulSoup4解析XML的方法小结
2020/12/07 Python
Clarks其乐鞋荷兰官网:Clarks荷兰
2019/07/05 全球购物
国贸类专业毕业生的求职信分享
2013/12/08 职场文书
化验室技术员岗位职责
2013/12/24 职场文书
情侣吵架检讨书
2014/02/05 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
银行优秀员工事迹材料
2014/05/29 职场文书
2015年大学迎新晚会总结
2015/07/16 职场文书
小学二年级语文教学反思
2016/03/03 职场文书
教师学期述职自我鉴定
2019/08/16 职场文书