说说如何在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 相关文章推荐
浅谈 javascript 事件处理
Jan 04 Javascript
手机端页面rem宽度自适应脚本
May 20 Javascript
jquery实现兼容IE8的异步上传文件
Jun 15 Javascript
教你如何终止JQUERY的$.AJAX请求
Feb 23 Javascript
用JS实现图片轮播效果代码(一)
Jun 26 Javascript
JS实现图片垂直居中显示小结
Dec 13 Javascript
JS简单验证上传文件类型的方法
Apr 17 Javascript
Angular父组件调用子组件的方法
Apr 02 Javascript
Angular4.x通过路由守卫进行路由重定向实现根据条件跳转到相应的页面(推荐)
May 10 Javascript
vue完成项目后,打包成静态文件的方法
Sep 03 Javascript
在vue里使用codemirror遇到的问题
Nov 01 Javascript
vue 微信扫码登录(自定义样式)
Jan 06 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
收音机玩机评测 406 篇视频合集
2020/03/11 无线电
php实现水仙花数的4个示例分享
2014/04/08 PHP
destoon实现调用自增数字从1开始的方法
2014/08/21 PHP
php cli配置文件问题分析
2015/10/15 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
php中分页及SqlHelper类用法实例
2017/01/12 PHP
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
PHP中define() 与 const定义常量的区别详解
2019/06/25 PHP
单击浏览器右上角的X关闭窗口弹出提示的小例子
2013/06/12 Javascript
扩展JS Date对象时间格式化功能的小例子
2013/12/02 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
JavaScript对象数组排序实例方法浅析
2016/06/15 Javascript
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
基于Marquee.js插件实现的跑马灯效果示例
2017/01/25 Javascript
小程序中canvas的drawImage方法参数使用详解
2019/07/04 Javascript
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
vue中动态select的使用方法示例
2019/10/28 Javascript
Vue混入mixins滚动触底的方法
2019/11/22 Javascript
使用Python和xlwt向Excel文件中写入中文的实例
2018/04/21 Python
Python实现的逻辑回归算法示例【附测试csv文件下载】
2018/12/28 Python
Python 函数返回值的示例代码
2019/03/11 Python
matplotlib grid()设置网格线外观的实现
2021/02/22 Python
Django和Ueditor自定义存储上传文件的文件名
2021/02/25 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
计算机软件个人的自荐信范文
2013/12/01 职场文书
楼面部长岗位职责范本
2014/02/14 职场文书
会计学自荐信
2014/06/03 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
股权转让协议书
2014/12/07 职场文书
劳动保障事务所个人工作总结
2015/08/12 职场文书
选调生挂职锻炼工作总结
2015/10/23 职场文书
Win11跳过联网界面创建本地管理账户的3种方法
2022/04/20 数码科技
阿里云 Windows server 2019 配置FTP
2022/04/28 Servers
MySQL聚簇索引和非聚簇索引的区别详情
2022/06/14 MySQL
GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结
2022/06/14 Golang