Files
pqs-9100_client/frontend/src/components/IpAddress/index.vue
2024-11-07 15:13:53 +08:00

361 lines
9.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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="$event => turnIpPosition(item, index, $event)"
@blur="handleBlur" @mouseup="handleMouseUp(index)" />
<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<HTMLInputElement[]>([]);
// 存储左右标识位
let markFlag = ref([
{
left: false,
right: false
},
{
left: false,
right: false
},
{
left: false,
right: false
},
{
left: false,
right: false
}
])
// 更新标识
let flag = ref(false)
// 鼠标点击
const handleMouseUp = (index: any) => {
let input = ipInputRefs.value[index]
// 全为false
markFlag.value.forEach(item => {
item.left = false
item.right = false
})
// 证明在开始阶段
if (input.selectionStart == 0) {
//console.log('鼠标设置了,', index)
markFlag.value[index].left = true
} else {
markFlag.value[index].left = false
}
// 证明在结束
if (input.selectionStart == (input.value || '').length) {
markFlag.value[index].right = true
} else {
markFlag.value[index].right = false
}
}
// 获取四个input refs
const getInputRef = (el: any, index: number) => {
if (el) {
ipInputRefs.value[index] = el;
}
};
// 声明IP存储类型
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) => {
let val = item.value;
//console.log(val, '===========')
// 处理非数字
val = val.toString().replace(/[^0-9]/g, "");
val = parseInt(val, 10);
if (isNaN(val)) {
val = "";
} else {
val = val < 0 ? 0 : val;
if (val > 255) {
// 判断val是几位数
let num = (val + '').length
if (num > 3) {
val = parseInt((val + '').substring(0, 3))
} else {
val = 255
}
}
}
item.value = val;
//console.log(item.value, '=========')
}
// 判断光标左右移动位置
const turnIpPosition = (item: IpType, index: number, event: any) => {
let e = event || window.event;
if (e.keyCode === 37) {
// 左箭头向左跳转,左一不做任何措施
if (index == 0) {
return
}
if (e.currentTarget.selectionStart === 0) {
if (markFlag.value[index].left) {
handleFocus(index - 1, 'toLeft')
markFlag.value[index].left = false
markFlag.value[index].right = false
} else {
console.log('左键设置了,', index)
markFlag.value[index].left = true
}
} else {
markFlag.value[index].right = false
markFlag.value[index].left = false
}
} else if (e.keyCode == 39) {
// 右箭头向右跳转,右一不做任何措施
markFlag.value[index].left = false
let start = e.currentTarget.selectionStart
if (index != 3 && start === item.value.toString().length) {
if (markFlag.value[index].right) {
handleFocus(index + 1, 'toRight')
markFlag.value[index].left = false
markFlag.value[index].right = false
} else {
markFlag.value[index].right = true
}
} else {
markFlag.value[index].right = false
}
} else if (e.keyCode === 8) {
//console.log('删除键把当前数据删除完毕后会跳转到前一个input')
// 删除键把当前数据删除完毕后会跳转到前一个input左一不做任何处理
if (index !== 0 && e.currentTarget.selectionStart === 0) {
if (markFlag.value[index].left) {
ipInputRefs.value[index - 1].focus();
markFlag.value[index].left = false
} else {
//console.log('左键设置了删除,', index)
markFlag.value[index].left = true
}
}
} else if (e.keyCode === 13 || e.keyCode === 32) {
//console.log('回车键、空格键、冒号均向右跳转,右一不做任何措施')
// 回车键、空格键、冒号均向右跳转,右一不做任何措施
if (index !== 3) {
ipInputRefs.value[index + 1].focus();
}
}
else if (e.keyCode === 110 || e.keyCode === 190) {
// 点 . 向右跳转,右一不做任何措施
// console.log('点击')
if (item.value == '') {
return
}
if (index !== 3) {
ipInputRefs.value[index + 1].select();
}
}
else if (item.value.toString().length === 3) {
//console.log('满3位光标自动向下一个文本框')
// 满3位光标自动向下一个文本框.
if (index !== 3) {
//ipInputRefs.value[index + 1].setSelectionRange(0, 0)
ipInputRefs.value[index + 1].focus();
}
}
}
// 处理聚焦
const handleFocus = (index: number, direction: string) => {
// 设置当前位置为选中状态 toRight:从左边来的
let input = ipInputRefs.value[index]
input.focus()
let value = input.value
// null 左右全部设置为true,可以直接跳转
if ((value || '').length == 0) {
markFlag.value[index].right = true
markFlag.value[index].left = true
} else {
if (direction == 'toRight') {
// 可以直接跳回
//console.log('右键focus,', index)
markFlag.value[index].left = true
// 设置光标为左边第一个
ipInputRefs.value[index].setSelectionRange(0, 0)
// 设置上一个的右边标识为false
markFlag.value[index - 1] && (markFlag.value[index - 1].right = false)
} else {
// 直接跳回
markFlag.value[index].right = true
// 设置后一个侧边为false
markFlag.value[index + 1] && (markFlag.value[index + 1].left = false)
}
}
}
// 格式化补零方法
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, () => {
//console.log('变化了~', props.value);
if(flag.value){
}else{
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)
flag.value = true
setTimeout(() => {
flag.value = false
}, 100)
}, {
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: 120%;
height: 35px;
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>