Vue.js实现数字输入框组件及双向数据绑定

作者:雾松

时间:2026-10-23

浏览:385

本文介绍如何在Vue.js中开发一个限制只能输入数字的自定义输入框组件。通过组件封装、监听器控制以及利用eval函数实现与父组件数据的双向绑定,解决单向绑定的局限,并提供扩展字母或中文输入的可能性。

文章目录

Vue.js数字输入框组件实现概述

在菜鸟教程学习Vue.js后,为了巩固知识并练习实战,尝试实现一个仅允许输入数字的输入框功能。此前曾使用jQuery实现过类似效果,此次改用Vue.js进行开发,并将具体实现过程记录下来。

若仅涉及单个输入框,实现难度较低。只需将输入框内容与数据绑定,并对该数据添加监听器即可。具体代码实现如下:

基础单向绑定实现


<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>Vue</title>
 <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
 <div id="div1">
 <input v-model="content">
 </div>
 <script>
 var mydata = new Vue({
 el: '#div1',
 data: {
 content: ''
 },
 watch: {
 content: function(val){
  this.content = val.replace(/\D/g, '')
 }
 }
 })
 </script>
</body>
</html>

然而,若页面或系统中存在大量此类输入框,上述方式并非最佳实践。为每个数据单独添加监听器会导致后续需求变更(如允许输入数字和字母)时修改成本极高。此外,该方式缺乏代码可移植性,迁移至其他系统时需重新编写。因此,需要编写通用方法以满足需求,此时应利用Vue的组件功能。新建一个名为num.js的文件,其内部代码如下:

通用组件封装与单向数据同步


Vue.component('number', {
 template: '<input type="text" v-model="con">',
 data: function(){
 return {
 con: ''
 }
 },
 watch: {
 con: function(val){
 this.con = val.replace(/\D/g, '');
 }
 }
})

上述代码定义了一个名为number的组件,内部包含一个输入框,其内容与数据con绑定,并通过监听器确保con的值仅包含数字。在HTML页面中引入num.js后,通过添加<number></number>标签即可在浏览器中渲染出该输入框。虽然页面放置输入框旨在供用户输入内容供程序使用,但获取输入内容的方式需符合Vue的设计理念。若使用jQuery,通常通过DOM操作获取值,但这与Vue数据与DOM分离的理念相悖。因此,应使输入框与特定数据绑定,以便程序直接获取数据。

Vue.js数字输入框组件实现概述

假设页面中有三个输入框,需分别将其内容绑定至val1、val2、val3。初始思路是在number标签上定义一个方法,当组件内con的值发生变化时触发该方法并传递con的值,该方法再调用父级mydata中的方法,经过两次传递将值赋给对应变量。这种逻辑较为繁琐,且使用者需在mydata中手动定义赋值方法,体验不佳。改进方案是:既然输入框需绑定数据,则应明确指定绑定的对象及属性名。例如,在number标签上指定对象为mydata,属性名为val1、val2或val3。传递对象时传入的是字符串'mydata'而非对象本身,如何在组件内使用该对象?此时需借助JavaScript中强大的eval函数。eval接收字符串参数,将其作为JavaScript代码解析并执行。具体代码如下:


<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title>vue</title>
 <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
 <script src="num.js"></script>
 </head>
 <body>
 <div id="div1">
 <number objname="mydata" keys="val1"></number>
 <number objname="mydata" keys="val2"></number>
 <number objname="mydata" keys="val3"></number>
 <p>第一个输入框的内容是: {{val1}}</p>
 <p>第二个输入框的内容是: {{val2}}</p>
 <p>第三个输入框的内容是: {{val3}}</p>
 </div>
 
 <script>
 var mydata = new Vue({
 el: '#div1',
 data: {
  val1: '',
  val2: '',
  val3: ''
 }
 })
 </script>
 </body>
</html>

num.js组件代码实现如下:


Vue.component('number', {
 props: ['objname', 'keys'],
 template: '<input type="text" v-model="con">',
 data: function(){
 return {
 con: ''
 }
 },
 watch: {
 con: function(val){
 this.con = val.replace(/\D/g, '');
 eval(this.objname+'[this.keys]=this.con');
 }
 },
})

运行效果如图所示:

Vue.js数字输入框组件实现概述

此时,输入框已限制仅能输入数字,并与数据实现了绑定。但需注意,这仅是单向绑定:输入框内容改变时,外部数据随之更新;然而,若外部数据发生变化,输入框内容并不会同步更新。为了验证这一点,可在页面下方添加三个普通输入框,分别绑定val1、val2、val3。

Vue.js数字输入框组件实现概述

实际操作页面时发现,上方自定义输入框内容的改变会影响下方普通输入框的显示,但反之则不成立,即下方输入框内容的改变不会影响上方自定义输入框。

Vue.js数字输入框组件实现概述

为实现反向绑定,需在组件内部为外部数据添加监听器。尽管拥有对象和属性名可以添加监听器,但需明确外部属性应绑定至哪个组件内的输入框。因此,需在number标签上增加一个ref属性,该属性是Vue定义的用于查找子组件的标识。最终代码调整为:

实现双向数据绑定


<div id="div1">
 <number ref="val1" objname="mydata" keys="val1"></number>
 <number ref="val2" objname="mydata" keys="val2"></number>
 <number ref="val3" objname="mydata" keys="val3"></number>
 <p>第一个输入框的内容是: {{val1}}</p>
 <p>第二个输入框的内容是: {{val2}}</p>
 <p>第三个输入框的内容是: {{val3}}</p>
 <input v-model="val1">
 <input v-model="val2">
 <input v-model="val3">
 </div>

num.js组件内部实现如下:


Vue.component('number', {
 props: ['objname', 'keys'],
 template: '<input type="text" v-model="con">',
 data: function(){
 return {
 con: ''
 }
 },
 mounted: function(){
 var self = this;
 window.addEventListener('load', function(){
 eval(self.objname+'.$watch(\''+self.keys+'\',function(val){this.$refs.'+self.keys+'.con=val})');
 })
 },
 watch: {
 con: function(val){
 this.con = val.replace(/\D/g, '');
 eval(this.objname+'[this.keys]=this.con');
 }
 },
})

组件优化与扩展建议

至此,数据实现了双向绑定。需注意,mounted生命周期中的addEventListener方法存在兼容性问题,IE8及以下版本不支持该方法,本文未做兼容处理。此外,代码仍有优化空间:观察number标签可知,ref和keys属性功能相似,是否可合并?经实验发现,在组件内部直接获取ref的值存在困难,目前尚未找到有效获取方式,技术深度有待加强。另外,objname参数是否必须传递?若不传递,可默认使用组件的父对象,此功能可实现。最后,组件还可进一步扩展,例如添加mytype属性:若不传值,默认仅允许输入数字;若设置为'word',则允许输入字母和数字;若设置为'chinese',则仅允许输入中文字符等。

更多教程请点击《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

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

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章