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

本文章记录,如何在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"/>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

灵眸边缘计算产品学习

EASY EAI灵眸科技 | 让边缘AI落地更简单 (easy-eai.com) 产品简介 支持4路1080P30fps视频流采集&#xff0c;四核CPU1.5GHz与2Tops AI边缘算力能力。集成有以太网、Wi-Fi、4G等网络通信外设&#xff1b;RS232、RS485、UART等本地通信接口。HDMI显示屏接口、音频输入输出等交互…

ntp时间适配服务器和ssh免密登录

1&#xff0e;配置ntp时间服务器&#xff0c;确保客户端主机能和服务主机同步时间 服务端server向阿里时间服务器进行时间同步 第一步&#xff1a;定位服务端server #安装软件 [rootserver ~]# yum install chrony -y # 编辑配置文件&#xff0c;定位第3行&#xff0c;修改…

小程序直播项目搭建

项目功能&#xff1a; 登录实时聊天点赞功能刷礼物取消关注用户卡片直播带货优惠券直播功能 项目启动&#xff1a; 1 小程序项目创建与配置&#xff1a; 第一步 需要登录小程序公众平台的设置页面进行配置&#xff1a; 首先需要是企业注册的才可以个人不能开通直播功能。服务类…

动态gif图怎么在线做?简单三步快速上手

使用gif动态图片能够增加图片的吸引力和趣味性&#xff0c;在很多社交平台上gif动态都是用来表达自己的心情的。而且&#xff0c;gif动图可以用于创意设计和艺术制作的宣传等。那么&#xff0c;要怎么制作呢&#xff1f;这时候使用gif制作&#xff08;https://www.gif.cn/&…

【学网攻】 第(6)节 -- 三层交换机实现VLAN间路由

文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节 -- 交换机划分Vlan【学网攻】 第(5)节 -- Cisco VTP的使用 前言 第5章给大家讲了VTP,也是为这节课铺垫,带领大家慢慢进入路由的区…

安全基础~通用漏洞2

文章目录 知识补充盲注Boolean盲注延时盲注报错注入二次注入 知识补充 盲注常用 if(条件,5,0) #条件成立 返回5 反之 返回0 left(database(),1)&#xff0c;database() #left(a,b)从左侧截取a的前b位 盲注 盲注就是在注入过程中&#xff0c;获取的数据不能回显至前端页面。 …

vivado: 设置里配置改了之后,总是在下次重启时重置的解决

我以前改字体大小&#xff0c;和改notepad编辑器都遇到&#xff0c;下一次打开就又是默认配置 解决&#xff1a; 1. c盘路径下&#xff0c;找到这个.xml文件&#xff0c;用记事本打开 2. 直接拉到记事本最后&#xff0c;我圈起来这里的路径不能有中文&#xff0c;所以要去把…

C++面试宝典第24题:袋鼠过河

题目 一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子。每隔一米就有一个桩子,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳得更远。每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5,就代表袋鼠下一跳最多能够跳5米;如果为0,就会陷进去无法…

【GitHub项目推荐--人脸识别】【转载】

01 带有移动应用程序的人脸识别库 OpenFace 作为用于人脸识别的通用库&#xff0c;能够实现瞬态和移动人脸识别&#xff0c;目前在 GitHub 上斩获 14291 Star。以下为 LFW 数据集 Sylvestor Stallone 输入单个图像的流程。 项目地址&#xff1a;https://github.com/cmusatya…

【zlm】针对单个设备的码率的设置

目录 代码修改 实验数据一 实验数据二 同时拉一路视频后 修改记录 使用方法 各库实操 代码修改 要被子类引用 &#xff0c;所以放在protected 不能放private 下面的结论&#xff0c;可以在下面的实验数据里引用。“同时拉一路视频后” 实验数据一 https://10.60.3.45:1…

【ZYNQ入门】第十篇、基于FPGA的图像白平衡算法实现

目录 第一部分、关于白平衡的知识 1、MATLAB 自动白平衡算法的实现 1.1、matlab代码 1.2、测试效果 1.3 测试源图 2、为什么摄像头采集的图像要做白平衡 3、自动白平衡算法总结 4、FPGA设计思路 4.1、实时白平衡的实现 4.2、计算流程优化思路 第二部分、硬件实…

机器学习之numpy库

机器学习之numpy库 numpy库概述numpy库历史numpy的核心numpy基础ndarray数组内存中的ndarray对象ndarray数组对象的特点ndarray数组对象的创建ndarray对象属性的基本操作数组的维度元素的类型数组元素的个数数组元素索引(下标) ndarray对象数组的自定义类型切片操作一维数组切片…

后端开发_单元测试

后端开发_单元测试 1. 简介2. JUnit 4使用方法2.1 jar包引入2.2 测试用例1. 简介 2. JUnit 4使用方法 2.1 jar包引入 1. 本地依赖引入方式 Junit4.jar包 2. maven方式引入jar <dep

AMIS的组件学习使用

部分代码片段 {"id": "filterForm","className": " xysd-zbkb-pubquery","labelWidth": 130,"body": [{"type": "grid","className": "xysd-grid-query-input","c…

多协议转BACnet网关BA110

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

【SGX系列教程】(一)Intel-SGX SDK在ubuntu22.04下安装全流程

文章目录 一.概述1.1 SGX三大组件1.2 SGXDataCenterAttestationPrimitives 二.安装流程2.1 检查服务器是否支持SGX2.2 sgx硬件/软件开启方法2.3 sgx dirver驱动安装&#xff1b;2.3.1 linux-sgx-driver驱动程序2.3.2 Intel SGX Support in the Linux Kernel&#xff08;linux内…

第11次修改了可删除可持久保存的前端html备忘录:将样式分离,可以自由秒添加秒删除样式

第11次修改了可删除可持久保存的前端html备忘录&#xff1a;将样式分离&#xff0c;可以自由秒添加秒删除样式 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"…

openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具)

文章目录 openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具)概述效果笔记编程环境界面控件的设置增加文件拖拽的类RSA证书和key是否匹配的实现在程序中加入环境变量备注备注END openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具) 概述 在学习openssl官方的…

小程序技术实践:快速开发适配鸿蒙的App

今年&#xff0c;在中国&#xff0c;被各大媒体和开发者称为“鸿蒙元年”。 在2023年底就有业内人士透露&#xff0c;华为明年将推出不兼容安卓的鸿蒙版本&#xff0c;未来IOS、鸿蒙、安卓将成为三个各自独立的系统。 果不其然&#xff0c;执行力超强的华为&#xff0c;与202…

latex加批注框

在Latex中加批注框&#xff1a; 效果如下&#xff1a; 方法 在对应位置加\todo{} As shown in \cref{fig:edit}, \todo{concrete description of example}.