vue+iview实现手机号分段输入框


Posted in Vue.js onMarch 25, 2022

vue + iview 实现一个手机分段的提示框,知识点还没总结,供大家参考,具体内容如下

vue+iview实现手机号分段输入框

<template>
  <div :class="{'ivu-form-item-error':!valid && dirty && validated}">
    <div class="ivu-phone-input ivu-select  ivu-select-multiple ivu-select-default" @keydown.delete.prevent @click.stop>
      <input type="text" class="ivu-select-selection number-block"
             v-for="(item,index) in phoneLength" :key="index"
             :ref="numberRefName+index"
             @focus="handlerFocus"
             @input="handlerInput($event,index)"
             @keydown.delete.prevent="deleteNumber($event,index)"
             @keydown.left.prevent="changeInput(index - 1)"
             @keydown.right="changeInput(index + 1)"
      />
      <Icon type="ios-close-circle" class="clean-btn" @click="cleanValue"/>
    </div>
  </div>
</template>
 
<script>
  export default {
    data() {
      return {
        required: this.$attrs.hasOwnProperty('required'),
        phoneLength: 11,
        phoneReg: /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
        numberRefName: 'numberBlock',
        validTimer: null,
        dirty: false,
        valid: false,
        validated: false,
      };
    },
    methods: {
 
      handlerFocus() {
        if (!this.dirty) {
          this.dirty = this.required ? true : false;
        }
      },
 
      handlerInput(e, index) {
        if (!e.target.value) {
          return;
        }
        this.dirty = true;
        let value = e.target.value.replace(/\D+/g, '');
        value = value ? value[0] : '';
        //合法值,切换下一个输入框
        if (value.length) {
          this.changeInput(index + 1);
        }
        //#end
        e.target.value = value;
        this.debounceValidate();
      },
      changeInput(index) {
        if (index < 0 || index === this.phoneLength) return;
        const target = this.$refs[this.numberRefName + index][0];
        target.focus();
        if (target.value && target.setSelectionRange) {
          target.setSelectionRange(1, 1);//maxlength="1" 时无效,所以去掉了...
        }
      },
      deleteNumber(e, index) {
        if (e.target.value) {
          e.target.value = ''
        } else {
          this.changeInput(index - 1);
        }
      },
      resetStatus() {
        this.validated = false;
        this.dirty = false;
      },
      cleanValue() {
        this.resetStatus();
        const numberBlocks = this.$refs;
        for (let i in numberBlocks) {
          numberBlocks[i][0].value = '';
        }
        if (this.required) {
          const FormItem = this.getFormItem();
          if (FormItem) {
            FormItem.resetField();
            FormItem.$emit('on-form-change', null);
          }
        }
        // this.changeInput(0);
      },
      debounceValidate() {
        this.validTimer = setTimeout(() => {
          this.validate();
        }, 300);
      },
      validate(isLeave) {
        const numberBlocks = this.$refs;
        let result = '';
        for (let i in numberBlocks) {
          result += numberBlocks[i][0].value;
        }
        if (result.length === this.phoneLength || isLeave) {
          this.validated = true;
          this.dispath({
            value: result,
            valid: this.valid = this.phoneReg.test(result),
          });
        }
      },
      dispath(info) {
        this.$emit('input', info.valid ? info.value : '');
        if (this.required) {
          const FormItem = this.getFormItem();
          if (FormItem) {
            this.updateFormItem(FormItem, info.valid ? info.value : '');
          }
        }
      },
      getFormItem() {
        let MAX_LEVEL = 3;
        let parent = this.$parent;
        let name = parent.$options.name;
        while (MAX_LEVEL && name !== 'FormItem') {
          MAX_LEVEL--;
          if (!parent) return null;
          parent = parent.$parent;
        }
        return parent || null;
      },
      updateFormItem(FormItem, data) {
        FormItem.$emit('on-form-change', data);
      },
      pageEvent() {
        if (this.dirty) {
          this.validate(true);
        }
      },
    },
    created() {
      window.addEventListener('click', this.pageEvent);
    },
    beforeDestroy() {
      window.removeEventListener('click', this.pageEvent);
    },
  };
</script>
 
<style scoped lang="less">
  .ivu-phone-input {
    .clean-btn {
      transition: opacity .5s;
      opacity: 0;
      cursor: pointer;
    }
    &:hover {
      .clean-btn {
        opacity: 1;
      }
    }
  }
 
  .number-block {
    display: inline-block;
    padding: 0;
    height: 30px;
    width: 28px;
    text-align: center;
    margin-right: 2px;
    &:nth-child(3) {
      margin-right: 10px;
    }
    &:nth-child(7) {
      margin-right: 10px;
    }
  }
</style>

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

Vue.js 相关文章推荐
vue 插槽简介及使用示例
Nov 19 Vue.js
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
Dec 01 Vue.js
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
Dec 02 Vue.js
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
vuex Module将 store 分割成模块的操作
Dec 07 Vue.js
vue下拉刷新组件的开发及slot的使用详解
Dec 23 Vue.js
Vue常用API、高级API的相关总结
Feb 02 Vue.js
手动实现vue2.0的双向数据绑定原理详解
Feb 06 Vue.js
Vue如何实现变量表达式选择器
Feb 18 Vue.js
vue实现列表拖拽排序的示例代码
Apr 08 Vue.js
vue打包时去掉所有的console.log
Apr 10 Vue.js
vue动态绑定style样式
Apr 20 Vue.js
Vue3中toRef与toRefs的区别
Mar 24 #Vue.js
一起来看看Vue的核心原理剖析
Mar 24 #Vue.js
深入讲解Vue中父子组件通信与事件触发
Mar 22 #Vue.js
关于Vue中的options选项
Mar 22 #Vue.js
vue+echarts实现多条折线图
vue使用echarts实现折线图
浅谈Vue的computed计算属性
You might like
一步一步学习PHP(5) 类和对象
2010/02/16 PHP
详解PHP中的null合并运算符
2015/12/30 PHP
php读取qqwry.dat ip地址定位文件的类实例代码
2016/11/15 PHP
PHP对象相关知识总结
2017/04/09 PHP
javascript引用对象的方法代码
2007/08/13 Javascript
Javascript与flash交互通信基础教程
2008/08/07 Javascript
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
15款优秀的jQuery导航菜单插件分享
2011/07/19 Javascript
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
JavaScript的strict模式与with关键字介绍
2014/02/08 Javascript
nodejs进阶(6)—连接MySQL数据库示例
2017/01/07 NodeJs
Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
2017/02/09 Javascript
js实现颜色阶梯渐变效果(Gradient算法)
2017/03/21 Javascript
JS实现汉字与Unicode码相互转换的方法详解
2017/04/28 Javascript
Vue Router的懒加载路径的解决方法
2018/06/21 Javascript
小程序扫描普通链接二维码跳转小程序指定界面方法
2019/05/07 Javascript
Node.js使用MongoDB的ObjectId作为查询条件的方法
2019/09/10 Javascript
python装饰器decorator介绍
2014/11/21 Python
python3使用PyMysql连接mysql数据库实例
2017/02/07 Python
Python编程判断一个正整数是否为素数的方法
2017/04/14 Python
python实战之实现excel读取、统计、写入的示例讲解
2018/05/02 Python
Python八皇后问题解答过程详解
2019/07/29 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
2019/08/12 Python
python基于event实现线程间通信控制
2020/01/13 Python
对tensorflow中tf.nn.conv1d和layers.conv1d的区别详解
2020/02/11 Python
python用opencv 图像傅里叶变换
2021/01/04 Python
基于python+selenium自动健康打卡的实现代码
2021/01/13 Python
使用Python+Appuim 清理微信的方法
2021/01/26 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
ebookers英国:隶属全球最大的在线旅游公司Expedia
2017/12/28 全球购物
FOREO斐珞尔官方旗舰店:LUNA露娜洁面仪
2018/03/11 全球购物
俄罗斯在线水暖商店:Perfecto.ru
2019/10/25 全球购物
医学院护理专业应届生求职信
2013/11/12 职场文书
旷课检讨书2000字
2014/01/14 职场文书
给校长的建议书200字
2014/05/16 职场文书
考试作弊检讨书
2014/10/21 职场文书