目录

1.双向绑定

2.:oninput动态绑定和@input事件处理

3.主要功能

4.自定义组件代码


1.双向绑定

实现双向绑定在vue2.x版本中是使用v-model实现的,本文子类中的主要代码如下:

export default {name: 'IpInput',model: {prop: 'ipAddress',event: 'change'},props: {ipAddress: {type: String,required: true},disabled: {type: Boolean,default: false}},methods: {// 失去焦点时判断输入是否完成,向父组件传递ipsubmitIp() {this.$nextTick(() => {if (!(this.ip1 === '') && !(this.ip2 === '') && !(this.ip3 === '') && !(this.ip4 === '')) {const ipVal = this.ip1 + '.' + this.ip2 + '.' + this.ip3 + '.' + this.ip4console.log(ipVal)this.$emit('change', ipVal)} else {return}})}}
}

父类中的调用如下

<ip-input v-model="tab.server" :disabled="tab.format !=='RTMP Push' && tab.format !=='RTMPS Push'" />

这里的tab.server值将会传给这个名为ipAddress的prop,同时当<ip-input>触发一个 change事件并附带一个新的值的时候,这个tab.server的property将会被更新。在submitIp()这个方法中调用this.$emit('change', ipVal)方法将新的值返回给父组件。

2.:oninput动态绑定和@input事件处理

1)使用oninput绑定,此方法会导致中文输入法情况下v-model和value不一致,原因是在中文输入法情况下vue中的v-model会自动return,value可变,但是v-mode绑定的值不变了。

oninput="value=value.replace(/[^0-9]/g, '')"

2)使用:oninput动态绑定,此方法必须在watch中搭配this.$nextTick(() => {})才能使dom数据正确更新,因为watch中使用了this.$refs.ip1.focus()来操作dom,vue中的dom是异步更新的,this.$nextTick(() => {})是一个微任务,在我看来类似Promise,ES6中Promise非常重要,像this.$store.dispatch(),axios等等都是Promise,主要是用来使异步任务通过.then()顺序执行,js的异步执行是先执行执行栈中的同步任务,执行栈为空后从任务队列中取数据,这里我也只是笼统的提一下,我自己也只是自学了一个月前端,还在学习状态,只了解点皮毛。

:oninput="ip1=ip1.replace(/[^0-9]/g, '')"

3)使用@input事件处理

@input="ip1=ip1.replace(/[^0-9]/g, '')"

这里@input和:oninput的区别在输出上主要是:

:oninput会在输入中文和英文的时候执行watch方法,说明这种情况下输入中文或英文会监听到输入框中ip的改变,且经我测试会执行两次。

@input情况下输入中文或英文不会执行watch方法,说明这种情况下输入中文或英文会直接改变值。

原因我猜测是:oninput是通过v-bind进行值绑定而@是v-on绑定的是事件,会直接执行里面的语句,希望懂的朋友在评论区指导一下。

3.主要功能

1)无法输入非数字,输入法情况下在输入完成后进行处理

2)输入三位数字后焦点自动向右跳转

3)按"↑"键焦点左移,按"↓"键焦点右移(这里暂时没有解决按左右键同时可以在输入框内部和输入框之间进行光标跳转,懂的朋友可以在评论区指导一下)

4)非0自动去除前面的0,例:036->36,000->0

5)输入框为空自动置0

4.自定义组件代码

自定义组件代码如下:

<template><div :class="disabled ? 'disabled' : ''" class="ip-box"><el-inputref="ip1":disabled="disabled"v-model="ip1"maxlength="3"@input="ip1=ip1.replace(/[^\d]/g,'')"@keyup.native="keyupEvent(1,$event)"@blur="syncIp1(),submitIp()"/><div class="ip-dot" /><el-inputref="ip2":disabled="disabled"v-model="ip2"maxlength="3"@input="ip2=ip2.replace(/[^\d]/g,'')"@keyup.native="keyupEvent(2,$event)"@blur="syncIp2(),submitIp()"/><div class="ip-dot" /><el-inputref="ip3":disabled="disabled"v-model="ip3"maxlength="3"@input="ip3=ip3.replace(/[^\d]/g,'')"@keyup.native="keyupEvent(3,$event)"@blur="syncIp3(),submitIp()"/><div class="ip-dot" /><el-inputref="ip4":disabled="disabled"v-model="ip4"maxlength="3"@input="ip4=ip4.replace(/[^\d]/g,'')"@keyup.native="keyupEvent(4,$event)"@blur="syncIp4(),submitIp()"/></div>
</template><script>
export default {name: 'IpInput',model: {prop: 'ipAddress',event: 'change'},props: {ipAddress: {type: String,required: true},disabled: {type: Boolean,default: false}},data() {return {ip1: '',ip2: '',ip3: '',ip4: ''}},watch: {'ip1': {handler: function() {this.$nextTick(() => {console.log(this.ip1)if (this.ip1.length === 3) {this.$refs.ip2.focus()}})}},'ip2': {handler: function() {this.$nextTick(() => {if (this.ip2.length === 3) {this.$refs.ip3.focus()}})}},'ip3': {handler: function() {this.$nextTick(() => {if (this.ip3.length === 3) {this.$refs.ip4.focus()}})}}},created() {if (this.ipAddress !== '') {// split()将字符串分割为子字符串数组const ipList = this.ipAddress.split('.')this.ip1 = ipList[0]this.ip2 = ipList[1]this.ip3 = ipList[2]this.ip4 = ipList[3]}},methods: {// 三位数自动跳转,ip超过255设置为255,去掉前面的0syncIp1() {if (this.ip1 === '') {this.ip1 = '0'} else if (parseInt(this.ip1) > 255) {this.ip1 = '255'this.$message({message: '这不是有效值,请指定一个0-255之间的值',type: 'error'})} else if (this.ip1 === '0' || this.ip1 === '00' || this.ip1 === '000') {this.ip1 = '0'} else {this.ip1 = this.ip1.replace(/\b(0+)/g, '')}},syncIp2() {if (this.ip2 === '') {this.ip2 = '0'} else if (parseInt(this.ip2) > 255) {this.ip2 = '255'this.$message({message: '这不是有效值,请指定一个0-255之间的值',type: 'error'})} else if (this.ip2 === '0' || this.ip2 === '00' || this.ip2 === '000') {this.ip2 = '0'} else {this.ip2 = this.ip2.replace(/\b(0+)/g, '')}},syncIp3() {if (this.ip3 === '') {this.ip3 = '0'} else if (parseInt(this.ip3) > 255) {this.ip3 = '255'this.$message({message: '这不是有效值,请指定一个0-255之间的值',type: 'error'})} else if (this.ip3 === '0' || this.ip3 === '00' || this.ip3 === '000') {this.ip3 = '0'} else {this.ip3 = this.ip3.replace(/\b(0+)/g, '')}},syncIp4() {if (this.ip4 === '') {this.ip4 = '0'} else if (parseInt(this.ip4) > 255) {this.ip4 = '255'this.$message({message: '这不是有效值,请指定一个0-255之间的值',type: 'error'})} else if (this.ip4 === '0' || this.ip4 === '00' || this.ip4 === '000') {this.ip4 = '0'} else {this.ip4 = this.ip4.replace(/\b(0+)/g, '')}},// 失去焦点时判断输入是否完成,向父组件传递ipsubmitIp() {if (!(this.ip1 === '') && !(this.ip2 === '') && !(this.ip3 === '') && !(this.ip4 === '')) {const ipVal = this.ip1 + '.' + this.ip2 + '.' + this.ip3 + '.' + this.ip4console.log(ipVal)this.$emit('change', ipVal)} else {return}},// 按下左键和右键焦点左右移动keyupEvent(index, e) {this.$nextTick(() => {// 按下'↑'键焦点左移if (e.keyCode === 38) {if (index === 2) {this.$refs.ip1.focus()} else if (index === 3) {this.$refs.ip2.focus()} else if (index === 4) {this.$refs.ip3.focus()}} else if (e.keyCode === 40) {// 按下'↓'键焦点右移if (index === 1) {this.$refs.ip2.focus()} else if (index === 2) {this.$refs.ip3.focus()} else if (index === 3) {this.$refs.ip4.focus()}}})}}
}
</script><style lang='scss' scoped>
.ip-box {width: 202px;border:1px solid #dcdfe6;border-radius: 5px;height: 38px; display: flex;align-items: center;justify-content: center;position: relative;>>> .el-input__inner {border: 0 !important;padding: 0;text-align: center;}>>> .el-input {width: 48px;}&.disabled {background-color: #f5f7fa;color: #c0c4cc;cursor: not-allowed;}
}
.ip-dot {margin-top: 7px;display: inline-block;width: 3px;height: 3px;border-radius: 50%;background-color: #606266;
}
.disabled {.ip-dot {background-color: #c0c4cc;}
}
</style>

其中使用了scss,需要使用sass-loader,选择合适项目的版本

npm install sass-loader@版本号 --save-dev

element-ui中若要改变样式需要使用>>>深度选择器,或者/deep/深度选择器

父组件中调用如下:

<ip-input v-model="tab.server" :disabled="tab.format !=='RTMP Push' && tab.format !=='RTMPS Push'" />

其中的v-model绑定的是ip地址,String类型,disabled是否禁用输入(只读),默认是false

若是绑定ipAddress是从后端读取的,由于源代码是将ipAddress的读取放在create()方法中的,因此会立即读取没有延迟,可修改如下:

watch: {'ipAddress': {handler(newName, oldName) {if (newName !== '') {// split()将字符串分割为子字符串数组const ipList = newName.split('.')this.ip1 = ipList[0]this.ip2 = ipList[1]this.ip3 = ipList[2]this.ip4 = ipList[3]}},immediate: true}}

博主只是自学前端一个月,这段代码肯定有可以优化的地方,可以写的更精简,有什么问题可以评论讨论

代码主体借鉴益达木咸醇的文章

vue2.x版本+element-ui2.15+版本实现只能输入数字的ip输入框,功能样式借鉴windows,与父组件双向绑定相关推荐

  1. vue 输入框限制3位小数_vue+element 中 el-input框 限制 只能输入数字及几位小数(自定义)和输入框之键盘...

    下布转数 v-model="scope.row.revolutions_count" placeholder="请输入" size="mini&quo ...

  2. vue限制只能输入数字_vue+element 中 el-input框 限制只能输入数字及一位小数

    仅个人经验,希望能帮到有需要的人. 第一次写 就话不多说了直接上代码. // 只能输入数字且只有一位小数 proving(e) { // this.form.skus[e].Price 是input的 ...

  3. Element 表单只能输入数字校验

    Element 表单只能输入数字校验 以下验证均为只能输入数字类型 只能输入整数 <el-input v-model="value" placeholder="请输 ...

  4. 正则:element ui input只能输入数字及数字后两位

    1:使用表单校验 <el-inputv-model="param.value"placeholder="起始备用金"/>value: [{ requ ...

  5. 基于Element ui 实现输入框只能输入数字并支持千分位

    实现效果 设置子组件 <template><el-inputref="money"v-model.trim="money":placehold ...

  6. element input 只能输入数字_Python之input()函数

    input()函数包含四个方面:input()函数的使用/结果的赋值/数据类型/结果的强制转换.是实现人机互动沟通的关键,需要在终端出输入信息.我们可以把input()函数当作一扇链接现实世界与代码世 ...

  7. element el-input设置只能输入数字 而且限制最大值

    <el-form-item label="付款金额:"><el-inputv-model="payformInline.paid_money" ...

  8. element input限制只能输入数字

    一.效果 目前这个el-input 属性只能输入数字. 二.参考资料以及理解 参考资料 操作思路: oninput:这是一个input 输入框在输入内容时会执行的事件(在输入框输入内容时就会触发 on ...

  9. 云原生生态周报 Vol.9| K8s v1.15 版本发布

    本周作者 | 衷源.心贵 业界要闻 1.Kubernetes Release v1.15 版本发布,新版本的两个主题是持续性改进和可扩展性.(https://github.com/kubernetes ...

最新文章

  1. 5G 信令流程 — ULCL 插入流程
  2. 《C++面向对象高效编程(第2版)》——3.4 赋值操作符
  3. java制作程序启动进度窗口
  4. 基于consul实现微服务的服务发现和负载均衡
  5. 仓库如何盘点 打印扫描一体PDA盘点机提升库存盘点效率
  6. 重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础
  7. 调整xfce中的鼠标大小到48以上-目前还没有完成
  8. .net 中应用 ValidationAttribute
  9. swift闭包的另一种用法
  10. 改进一个asp.net通用分页显示辅助类
  11. ExeScope辅助测试工具简介
  12. Tomcat8正确配置环境变量详细方法
  13. dnf php的补丁放哪,DNF模型文件在哪 补丁玩家必备知识
  14. html怎么让视频自动循环播放,【前端】div 加载视频并自动循环播放
  15. irr内部收益率php,内部收益率(IRR)
  16. Android6.0权限的处理
  17. 人工智能和自动化之间,主要有区别吗?
  18. Vue学习笔记(一) 基础+指令+侦听器+计算属性+vue-cli
  19. 滴滴抢单 java_今天我体验了下传说估值100亿美金的「滴滴拉屎」App,出门再也不愁找厕所了...
  20. O2O模式为什么这么火

热门文章

  1. JSP的九大内置对象和四个作用域
  2. poi中word中表格跨列合并以及不兼容wps问题,java下 linux下word转pdf 问题解决
  3. 生产环境WEB服务管理脚本之监控脚本
  4. EDM邮件营销ip预热
  5. h5邮件的邮箱 支持_Coremail发布H5邮箱移动模板新版本,多项新功能让办公更便捷...
  6. 无法识别 移动固态硬盘_M.2固态硬盘不能识别怎么办 Bios开启CSM识别M.2固态硬盘方法...
  7. MySQl建库建表及增删改查
  8. 一文彻底讲清Linux tty子系统架构及编程实例
  9. 如何聪明的提问(职场的必踩坑)
  10. 新增网络与信息安全​专硕!优秀双非重庆邮电大学