【前端小点】Vue3中的IP输入框组件

news2024/12/23 21:03:58

本文章记录,如何在vue3项目开发中,使用ip输入框组件.
之前写过vue2版本的ip组件,为了更好的适应vue3,此次进行vue3代码重写
先上效果图:
在这里插入图片描述
禁用效果图:
在这里插入图片描述
主要是组件的开发,代码如下,可直接拷贝使用.
大概思路就是: 使用四个输入框拼接,然后给输入内容添加校验操作,添加光标移动,
使用v-model语法糖特性

组件: IpAddress.vue
<template>
  <div :class="{ 'disabled': disabled }">
    <ul class="ipAdress">
      <li v-for="(item, index) in ipAddress" :key="index">
        <input :ref="el => getInputRef(el, index)" v-model="item.value" type="text" class="ipInputClass"
          :disabled="disabled" @input="checkIpVal(item)" @keyup="turnIpPosition(item, index, $event)"
          @blur="handleBlur" />
        <div></div>
      </li>
    </ul>
  </div>
</template>

<script lang="ts" setup name="routePage">
import { ref, watch } from 'vue'

// 接收来自上层的数据
const props = defineProps(['value', 'disabled'])

// 更新数据
const $emits = defineEmits(['update:value', 'blur'])

// 存储四个ref
const ipInputRefs = ref<HTMLElement[]>([]);
// 获取refs
const getInputRef = (el: any, index: number) => {
  if (el) {
    ipInputRefs.value[index] = el;
  }
};
// 声明类型
interface IpType {
  value: string
}
// 要显示的四个ip
let ipAddress = ref<IpType[]>([
  {
    value: "",
  },
  {
    value: "",
  },
  {
    value: "",
  },
  {
    value: "",
  },
])
// 初始化显示数据
const initShowData = () => {
  // 判断不合理行为
  if (props.value === '') {
    ipAddress.value.forEach(item => {
      item.value = ''
    })
  } else {
    let ipList = props.value.split('.')
    ipAddress.value.forEach((item: IpType, index: number) => {
      item.value = ipList[index]
    })
  }
}

// 检查ip输入
const checkIpVal = (item: any) => {
  //确保每个值都处于0-255
  let val = item.value;
  // 处理非数字
  val = val.toString().replace(/[^0-9]/g, "");
  val = parseInt(val, 10);
  if (isNaN(val)) {
    val = "";
  } else {
    val = val < 0 ? 0 : val;
    val = val > 255 ? 255 : val;
  }
  item.value = val;
}

// 判断光标位置
const turnIpPosition = (item: IpType, index: number, event: any) => {
  let e = event || window.event;
  if (e.keyCode === 37) {
    // 左箭头向左跳转,左一不做任何措施
    if (index !== 0 && e.currentTarget.selectionStart === 0) {
      ipInputRefs.value[index - 1].focus();
    }
  } else if (e.keyCode == 39) {
    // 右箭头向右跳转,右一不做任何措施
    if (
      index !== 3 &&
      e.currentTarget.selectionStart === item.value.toString().length
    ) {
      ipInputRefs.value[index + 1].focus();
    }
  } else if (e.keyCode === 8) {
    // 删除键把当前数据删除完毕后会跳转到前一个input,左一不做任何处理
    if (index !== 0 && item.value === "") {
      ipInputRefs.value[index - 1].focus();
    }
  } else if (e.keyCode === 13 || e.keyCode === 32) {
    // 回车键、空格键、冒号均向右跳转,右一不做任何措施
    if (index !== 3) {
      ipInputRefs.value[index + 1].focus();
    }
  }
  // else if (item.value.toString().length === 3) {
  //   // 满3位,光标自动向下一个文本框.
  //   if (index !== 3) {
  //     ipInputRefs.value[index + 1].focus();
  //   }
  // }
  else if (e.keyCode === 110 || e.keyCode === 190) {
    // 点 . 向右跳转,右一不做任何措施
    if (
      index !== 3 &&
      e.currentTarget.selectionStart !== 0
    ) {
      ipInputRefs.value[index + 1].focus();
    }
  }
}
// 格式化补零方法
const formatter = (val: string) => {
  let value = val.toString();
  if (value.length === 2) {
    value = "0" + value;
  } else if (value.length === 1) {
    value = "00" + value;
  } else if (value.length === 0) {
    value = "000";
  }
  return value;
}

// 监听数据变化,并初始化显示四个数据
watch(() => props.value, () => {
  initShowData()
}, {
  immediate: true
})
// 监听ipAddress数据变化
watch(ipAddress, () => {
  let str = "";
  for (const i in ipAddress.value) {
    str += formatter(ipAddress.value[i].value);
  }
  if (str === "000000000000") {
    str = "";
  } else {
    str = ipAddress.value.map(item => {
      if (item.value !== null) {
        return item.value + ''
      } else {
        return '0'
      }
    }).join(".")
  }
  $emits('update:value', str)
}, {
  deep: true
})

const handleBlur = () => {
  $emits('blur')
}

</script>
<style lang="scss" scoped>
.disabled {
  cursor: not-allowed;
  background-color: #f5f7fa;

  .ipAdress {
    li {
      .ipInputClass {
        color: #c3c4cc;
        cursor: not-allowed;
      }
    }
  }
}

.ipAdress {
  display: flex;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  line-height: 40px;
  width: 100%;
  height: 40px;
  padding-inline-start: 0px;
  padding-left: 10px;
  padding-right: 10px;
  box-sizing: border-box;
  margin: 0;
}

.ipAdress li {
  position: relative;
  margin: 0;
  list-style-type: none;
}

.ipInputClass {
  border: none;
  width: 50px;
  height: 23px;
  text-align: center;
  color: #606266;
  background: transparent;
}

.ipAdress li div {
  position: absolute;
  bottom: 12px;
  right: 0;
  border-radius: 50%;
  background: #b6b8bc;
  width: 2px;
  height: 2px;
}

/*只需要3个div*/
.ipAdress li:last-child div {
  display: none;
}

/*取消掉默认的input focus状态*/
.ipAdress input:focus {
  outline: none;
}
</style>

注册为组件以后,在页面中使用如下,当然,组件名自己定义,我这里组件名是IpAddress

// ipAddress双向绑定,handleBlur 可以在失去光标时,做校验等操作
<IpAddress v-model:value="ipAddress" @blur="handleBlur" :disabled="true"/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1406575.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

05 双向链表

目录 1.双向链表 2.实现 3.OJ题 4.链表和顺序表对比 1. 双向链表 前面写了单向链表&#xff0c;复习一下 无头单向非循环链表&#xff1a;结构简单&#xff0c;一般不会单独用来存数据。实际中更多作为其他数据结构的子结构&#xff0c;如哈希桶、图的邻接等。另外这种结构在…

你知道Mysql的架构吗?

msyql分为server曾和存储引擎层 server层包括了连接器(管理连接&#xff0c;权限验证)、查询缓存&#xff08;命中直接返回结果&#xff09;、分析器&#xff08;词法分析&#xff0c;语法分析&#xff09;、优化器&#xff08;执行计划生成&#xff0c;索引选择&#xff09;、…

浪花 - 查询队伍列表

一、接口设计 1. 请求参数&#xff1a;封装 TeamQuery package com.example.usercenter.model.dto;import com.example.usercenter.common.PageRequest; import lombok.Data;/*** author 乐小鑫* version 1.0* Date 2024-01-22-20:14*/ Data public class TeamQuery extends …

使用Unity创建VisionPro应用

1、下载特定Unity版本 Unity账号需要是Pro账号,普通账号不行,目前只支持这1个Unity版本,不要下载任何其它版本:unityhub://2022.3.11f1/d00248457e15) 其它条件:使用Mac电脑M系列芯片,XCode15 Beta2及以上 参考资料: 苹果官网:苹果官网 Unity官网:Unity官网 官方教程…

C#,生成图片的指定尺寸缩略图的源代码

编程的时候经常用到图像的缩略图。 本文发布一个用于生成指定尺寸的缩略图的简单方法。 1 文本格式 private void button1_Click(object sender, EventArgs e) { CreateThumbnail("demo.jpg", "demo_thumb.jpg", 128, 128); } private void CreateTh…

MySQL函数—日期函数

MySQL函数—日期函数 函数功能CURDATE()返回当前日期&#xff0c;只有年月日CURTIME()返回当前时间&#xff0c;只有时分秒NOW()返回当前日期和时间 年月日时分秒YEAR(date)获取指定date的年份MONTH(date)获取指定date的月份DAY(date)获取指定date的日期DATE_ADD(date,INTERVAL…

项目解决方案: 视频融合(实时监控视频和三维建模进行融合)设计方案

目 录 一、需求描述 1、视频接入和控制要求 2、视频播放需求 3、提供其他应用的调用 二、方案设计 &#xff08;一&#xff09;系统设计图 &#xff08;二&#xff09;产品实现方案 三、产品和功能描述 &#xff08;一&#xff09;总体描述 &#xf…

2024问题汇总

2024问题汇总 Linux1.df-h / df -i 命令2.为多网卡Linux云服务器配置策略路由 Windows1.快速进入控制面板 网络连接指令 Linux 1.df-h / df -i 命令 df -h / df -i 都表示查看磁盘空间使用信息 如果遇到磁盘快满的情况&#xff0c;用这两个命令区别如下 df -h 是去删除比较大 …

Java的异常 Exception

从继承关系可知:Throwable 是异常体系的根&#xff0c;它继承自Object 。Throwable 有两个体系: Error 和Exception. Error表示严重的错误&#xff0c;程序对此一般无能为力,例如: OutOfMemoryError :内存耗尽NoClassDefFoundError :无法加载某个ClassStackOverflowError :虚…

web安全学习笔记【05】——反弹Shell、正反向连接

思维导图 #知识点&#xff1a; 1、Web常规-系统&中间件&数据库&源码等 2、Web其他-前后端&软件&Docker&分配站等 3、Web拓展-CDN&WAF&OSS&反向&负载均衡等 ----------------------------------- 1、APP架构-封装&原生态&H5&am…

软件安全测试的重要性简析,专业安全测试报告如何申请?

在当今数字化时代&#xff0c;软件在我们的日常生活中扮演着至关重要的角色&#xff0c;但也带来了各种潜在的安全威胁。为了保障用户的信息安全和维护软件的可靠性&#xff0c;软件安全测试显得尤为重要。 软件安全测试是指通过一系列的方法和技术&#xff0c;对软件系统中的…

BACnet转Modbus协议转换网关BA111

随着通讯技术和控制技术的发展&#xff0c;为了实现楼宇的高效、智能化管理&#xff0c;集中监控管理已成为楼宇智能管理发展的必然趋势。在此背景下&#xff0c;高性能的楼宇暖通数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于楼宇自控和暖通空调系统应用中…

Webpack5 基本使用 - 2

常用 loader loader 是辅助打包工具。webpack 默认只能打包 js 文件&#xff0c;打包其它模块就需要配置 loader 来告诉 webpack 该怎么去打包其它文件。loader 可以将文件从不同的语言转换为 JavaScript。一类文件如果需要多个 loader 处理&#xff0c;loader 的执行顺序是从…

数据采集与预处理01: 项目1 数据采集与预处理准备

数据采集与预处理01&#xff1a; 项目1 数据采集与预处理准备 任务1 认识数据采集技术&#xff0c;熟悉数据采集平台 数据采集&#xff1a;足够的数据量是企业大数据战略建设的基础&#xff0c;因此数据采集成为大数据分析的前站。数据采集是大数据价值挖掘中重要的一环&#…

《WebKit 技术内幕》学习之十二(2):安全机制

2 沙箱模型 2.1 原理 一般而言&#xff0c;对于网络上的网页中的JavaScript代码和插件是不受信的&#xff08;除非是经过认证的网站&#xff09;&#xff0c;特别是一些故意设计侵入浏览器运行的主机代码更是非常危险&#xff0c;通过一些手段或者浏览器中的漏洞&#xff0c…

在SpringBoot中基于CanvasLabel的地震基础信息展示实践

目录 前言 一、数据库设计 1、数据库设计 2、sql脚本 3、数据记录 二、SpringBoot后台设计与实现 1、Mapper访问层及实体定义 2、Service层实现 3、控制层实现 三、地震信息展示 1、展示数据接入 2、最终效果 总结 前言 在上一篇博客中&#xff0c;对于在Leafle…

自然语言处理--基于HMM+维特比算法的词性标注

自然语言处理作业2--基于HMM维特比算法的词性标注 一、理论描述 词性标注是一种自然语言处理技术&#xff0c;用于识别文本中每个词的词性&#xff0c;例如名词、动词、形容词等&#xff1b; 词性标注也被称为语法标注或词类消疑&#xff0c;是语料库语言学中将语料库内单词…

mockjs使用(2)

mockjs使用&#xff08;1&#xff09; 4、Mock 4.1 Mock.mock() 根据数据模版生成模拟数据 Mock.mock( rurl?, rtype?, template|function(options) )问号代表该参数不必填 4.1.1 各参数及其默认值 rurl: 不必填。表示需要拦截的URL&#xff0c;可以使URL字符串或URL正…

解决方案 | 基于SFTP协议的文件传输断点续传Java实现方案

背景 因项目需要&#xff0c;我们服务每天都需要通过SFTP协议来对接上下游进行文件传输&#xff0c;但是对于一些大文件&#xff0c;在与第三方公司的服务器对接过程中很可能会因为网络问题或上下游服务器性能问题导致文件上传或者下载被中断&#xff0c;每次重试都需要重新对…