Vue数字输入框组件使用方法详解


Posted in Javascript onFebruary 10, 2020

前面的话

关于基础组件介绍,已经更新完了。这篇文章将用组件基础知识开发一个数字输入框组件。将涉及到指令、事件、组件间通信。

Vue数字输入框组件使用方法详解

基础需求

  • 只能输入数字
  • 设置初始值,最大值,最小值
  • 在输入框聚焦时,增加对键盘上下键的支持
  • 增加一个控制步伐prop-step,例如,设置为10 ,点击加号按钮,一次增加10

项目搭建

在了解需求后,进行项目的初始化:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
 <div id="app">
 <input-number></input-number>
 </div>
</body>
</html>
<script>
 Vue.component('input-number',{
 template: `
  <div class="input-number">
  <input type="text" />
  <button>-</button>
  <button>+</button>
  </div>
 `}
 var app = new Vue({
 el:'#app'
 })
</script>

初始化结构搭好后,由于要设置初始值,最大值、最小值,我们在父组件中的 < input-number>< /input-number>上设置这些值,并且通过Props将父组件数据传递给子组件

父组件中添加数据:value是一个关键的绑定值,所以用v-model,实现双向绑定。

<input-number v-model="value" :max="100" :min="0"></input-number>

在子组件中添加props选项:

props: {
  max: {
  type: Number,
  default: Infinity
  },
  min: {
  type: Number,
  default: -Infinity
  },
  value: {
  type: Number,
  default: 0
  }
 },

我们知道,Vue组件时单项数据流,所以无法在子组件上更改父组件传递的数据,在这里子组件只改变value值,所以我们给子组件设置一个data数据,默认引用value值,然后在组件内部维护这个data。

data() {
  return{
  // 保存初次父组件传递的数据
  currentValue : this.value,
  }
 }

并且给子组件的input元素绑定value

<input type="text" :value="currentValue" />

这样只解决了初始化时引用父组件value的问题,但是如果父组件修改了value,子组件无法感知,我们想要currentValue一起更新。那么就要使用wacth监听选项监听value。

  • 当父组件value发生变化时,子组件currentValue也跟着变化。
  • 当子组件currentValue变化时,使用$emit触发v-model,使得父组件value也跟着变化
watch: {
  // 监听属性currentValue与value
  currentValue(val) {
  // currentValue变化时,通知父组件的value也变化
  this.$emit('input', val);
  

  },
  value(val) {
  // 父组件value改变时,子组件currentValue也改变
  this.updataValue(val);
  }
 },
 methods: {
  updataValue(val) {
  if(val > this.max) val = this.max;
  if(val < this.min) val = this.min;
  this.currentValue = val;
  }
  },
  // 第一次初始化时,也对value进行过滤
 mounted: function() {
  this.updataValue(this.value);
 }

上述代码中,生命周期mounted钩子也使用了updateValue()方法,是因为初始化时也要对value进行验证。

父子间的通信解决差不多了,接下来完成按钮的操作:添加handleDown与handleUp方法

template: `
  <div class="input-number">
  <input type="text" :value="currentValue" />
  <button @click="handleDown" :disabled="currentValue <= min">-</button>
  <button @click="handleUp" :disabled="currentValue >= max">+</button>
  </div>
 `,
  methods: {
  updataValue(val) {
  if(val > this.max) val = this.max;
  if(val < this.min) val = this.min;
  this.currentValue = val;
  },
  // 点击减号 减10
  handleDown() {
  if(this.currentValue < this.min) return 
  this.currentValue -= this.prop_step;
  },
  // 点击加号 加10 
  handleUp() {
  if(this.currentValue < this.min) return
  this.currentValue += this.prop_step;
  },

当用户在输入框想输入具体的值时,怎么办?

为input绑定原生change事件,并且判断输入的是否数字:

<input type="text" :value="currentValue" @change="handleChange" />

在methods选项中,添加handleChange方法:

// 输入框输入值
 handleChange(event) {
 var val = event.target.value.trim();
 var max = this.max;
 var min = this.min;
  if(isValueNumber(val)) {
   val = Number(val);
   if(val > max) {
   this.currentValue = max;
   }
   if(val < min) {
   this.currentValue = min;
   }
   this.currentValue = val;
   console.log(this.value);
  }else {
   event.target.value = this.currentValue;
  }

在外层添加判断是否为数字的方法isValueNumber:

function isValueNumber(value) {
 return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value+ '');
 }

到此一个数字输入框组件基本完成,但是前面提出的后两个要求也需要实现,很简单,在input上绑定一个keydown事件,在data选项中添加数据prop_step

<input type="text" :value="currentValue" @change="handleChange" @keydown="handleChange2" />
data() {
  return{
  // 保存初次父组件传递的数据
  currentValue : this.value,
  prop_step: 10
  }
 }
// 当聚焦时,按上下键改变
  handleChange2(event) {
  console.log(event.keyCode)
  if(event.keyCode == '38') {
   this.currentValue ++;
  }
  if(event.keyCode == '40') {
   this.currentValue --;
  }
  }

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
 <div id="app">
  <input-number v-model="value" :max="100" :min="0"></input-number>
 </div>
</body>
</html>
<script>
 function isValueNumber(value) {
  return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value+ '');
 }
 Vue.component('input-number',{
  props: {
   max: {
    type: Number,
    default: Infinity
   },
   min: {
    type: Number,
    default: -Infinity
   },
   value: {
    type: Number,
    default: 0
   }
  },
  template: `
   <div class="input-number">
    <input type="text" :value="currentValue" @change="handleChange" @keydown="handleChange2" />
    <button @click="handleDown" :disabled="currentValue <= min">-</button>
    <button @click="handleUp" :disabled="currentValue >= max">+</button>
   </div>
  `,
  data() {
   return{
    // 保存初次父组件传递的数据
    currentValue : this.value,
    prop_step: 10
   }
  },
  watch: {
   // 监听属性currentValue与value
   currentValue(val) {
   // currentValue变化时,通知父组件的value也变化
   this.$emit('input', val);
   

   },
   value(val) {
   // 父组件value改变时,子组件currentValue也改变
    this.updataValue(val);
   }
  },
  methods: {
   updataValue(val) {
    if(val > this.max) val = this.max;
    if(val < this.min) val = this.min;
    this.currentValue = val;
   },
   // 点击减号 减10
   handleDown() {
    if(this.currentValue < this.min) return 
    this.currentValue -= this.prop_step;
   },
   // 点击加号 加10 
   handleUp() {
    if(this.currentValue < this.min) return
    this.currentValue += this.prop_step;
   },
   // 输入框输入值
   handleChange(event) {
    var val = event.target.value.trim();
    var max = this.max;
    var min = this.min;
    if(isValueNumber(val)) {
     val = Number(val);
     if(val > max) {
      this.currentValue = max;
     }
     if(val < min) {
      this.currentValue = min;
     }
     this.currentValue = val;
     console.log(this.value);
    }else {
     event.target.value = this.currentValue;
    }
   },
   // 当聚焦时,按上下键改变
   handleChange2(event) {
    console.log(event.keyCode)
    if(event.keyCode == '38') {
     this.currentValue ++;
    }
    if(event.keyCode == '40') {
     this.currentValue --;
    }
   }

  },
  // 第一次初始化时,也对value进行过滤
  mounted: function() {
   
   this.updataValue(this.value);
  }


 })
 var app = new Vue({
  el:'#app',
  data:{
   value: 5
  }
 })
</script>

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

Javascript 相关文章推荐
整理8个很棒的 jQuery 倒计时插件和教程
Dec 12 Javascript
php析构函数的具体用法小结
Mar 11 Javascript
Js实现滚动变色的文字效果
Jun 16 Javascript
JavaScript forEach()遍历函数使用及介绍
Jul 08 Javascript
利用jQuery设计一个简单的web音乐播放器的实例分享
Mar 08 Javascript
浅谈js基本数据类型和typeof
Aug 09 Javascript
vue.js入门(3)——详解组件通信
Dec 02 Javascript
javascript中new Array()和var arr=[]用法区别
Dec 01 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
Apr 11 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
May 21 Javascript
关于layui表单中按钮自动提交的解决方法
Sep 09 Javascript
浅谈nuxtjs校验登录中间件和混入(mixin)
Nov 06 Javascript
JavaScript canvas实现跟随鼠标事件
Feb 10 #Javascript
JavaScript实现简易聊天对话框(加滚动条)
Feb 10 #Javascript
node.js使用 http-proxy 创建代理服务器操作示例
Feb 10 #Javascript
node.js中 redis 的安装和基本操作示例
Feb 10 #Javascript
js实现登录拖拽窗口
Feb 10 #Javascript
javascript 原型与原型链的理解及应用实例分析
Feb 10 #Javascript
在 Vue 中使用 JSX 及使用它的原因浅析
Feb 10 #Javascript
You might like
Protoss兵种对照表
2020/03/14 星际争霸
Thinkphp中的volist标签用法简介
2014/06/18 PHP
在Debian系统下配置LNMP的教程
2015/07/09 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
2016/07/07 PHP
根据鼠标的位置动态的控制层的位置
2009/11/24 Javascript
jquery maxlength使用说明
2011/09/09 Javascript
js的Prototype属性解释及常用方法
2014/05/08 Javascript
node.js中的fs.chown方法使用说明
2014/12/16 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
JS+CSS实现大气的黑色首页导航菜单效果代码
2015/09/10 Javascript
基于JS实现新闻列表无缝向上滚动实例代码
2016/01/22 Javascript
两种方法解决javascript url post 特殊字符转义 + &amp; #
2016/04/13 Javascript
jQuery实现的tab标签切换效果示例
2016/09/05 Javascript
jQuery实现动态文字搜索功能
2017/01/05 Javascript
详解JSON和JSONP劫持以及解决方法
2019/03/08 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
详解Vue中组件的缓存
2019/04/20 Javascript
详解微信小程序开发用户授权登陆
2019/04/24 Javascript
详解关于表格合并span-method方法的补充(表格数据由后台动态返回)
2019/05/21 Javascript
JavaScript和TypeScript中的void的具体使用
2019/09/12 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
vue中 v-for循环的用法详解
2020/02/19 Javascript
Python使用Redis实现作业调度系统(超简单)
2016/03/22 Python
python爬虫 使用真实浏览器打开网页的两种方法总结
2018/04/21 Python
Django Web开发中django-debug-toolbar的配置以及使用
2018/05/06 Python
Python简单实现网页内容抓取功能示例
2018/06/07 Python
django2用iframe标签完成网页内嵌播放b站视频功能
2018/06/20 Python
教你利用Python玩转histogram直方图的五种方法
2018/07/30 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
2019/08/13 Python
pycharm激活码2020最新分享适用pycharm2020最新版亲测可用
2020/11/22 Python
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
SQL Server里面什么样的视图才能创建索引
2015/04/17 面试题
规范化管理年活动总结
2014/08/29 职场文书
硕士毕业论文导师评语
2014/12/31 职场文书
创先争优活动个人总结
2015/03/04 职场文书
大学毕业论文致谢词
2015/05/14 职场文书