You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
5.3 KiB
216 lines
5.3 KiB
7 months ago
|
<!-- @format -->
|
||
|
|
||
|
<template>
|
||
|
<div class="ipInputContain">
|
||
|
<div
|
||
|
class="ipInputBox"
|
||
|
v-for="(item, index) in defaultValue"
|
||
|
:key="index"
|
||
|
@mouseover="
|
||
|
() => {
|
||
|
flag = index;
|
||
|
}
|
||
|
"
|
||
|
@mouseleave="
|
||
|
() => {
|
||
|
flag = null;
|
||
|
}
|
||
|
">
|
||
|
<!-- 包裹的error外边框 -->
|
||
|
<!-- 需求修改内部边框警示去除 -->
|
||
|
<!-- <div :class="activeIndex[index] ? 'active' : ''"> -->
|
||
|
<ns-input
|
||
|
type="number"
|
||
|
class="ipInput"
|
||
|
:value="defaultValue[index]"
|
||
|
@change="onChange(index, $event)"
|
||
|
@keydown="onKeyDown(index, $event)"
|
||
|
@keyup="onKeyUp(index, $event)"
|
||
|
@blur="onBlur" />
|
||
|
<!-- </div> -->
|
||
|
<div class="tips" v-show="flag == index ? true : false">0~255</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
<script>
|
||
|
import { defineComponent } from 'vue';
|
||
|
// 导入的报错icon
|
||
|
// import { CloseCircleOutlined } from '@ant-design/icons-vue';
|
||
|
export default defineComponent({
|
||
|
name: 'NsInputIp',
|
||
|
// 传入的报错icon
|
||
|
// components: { CloseCircleOutlined },
|
||
|
props: {
|
||
|
modelValue: {
|
||
|
type: String,
|
||
|
default: '',
|
||
|
},
|
||
|
// defaultValue: {
|
||
|
// type: Array,
|
||
|
// default: () => {
|
||
|
// return ['', '', '', ''];
|
||
|
// },
|
||
|
// },
|
||
|
},
|
||
|
emits: ['change', 'updata:modelValue'],
|
||
|
setup(props, { attrs }) {
|
||
|
let defaultValue = ['', '', '', ''];
|
||
|
let ipValue = props.modelValue;
|
||
|
if (ipValue) {
|
||
|
let newValue = ipValue.split('.');
|
||
|
defaultValue = newValue;
|
||
|
}
|
||
|
return { defaultValue };
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
// ip: [1, 2, 3, 4],
|
||
|
// 控制下弹框显示隐藏
|
||
|
flag: null,
|
||
|
// value: [null, null, null, null],
|
||
|
// 边框警示
|
||
|
activeIndex: [false, false, false, false],
|
||
|
// ipAddress: new Array(4),
|
||
|
ipAddress: ['', '', '', ''],
|
||
|
errShow: false,
|
||
|
ipResult: '',
|
||
|
};
|
||
|
},
|
||
|
watch: {
|
||
|
defaultValue() {},
|
||
|
},
|
||
|
mounted() {
|
||
|
// console.log(newValue);
|
||
|
// eslint-disable-next-line vue/no-mutating-props
|
||
|
// this.defaultValue = newValue;
|
||
|
},
|
||
|
methods: {
|
||
|
onKeyDown() {},
|
||
|
onBlur(e) {
|
||
|
// let value = e.target.value;
|
||
|
const res = this.ipAddress.some((item) => item === '');
|
||
|
// console.log(typeof(this.ipAddress[1]));
|
||
|
if (res) {
|
||
|
this.errShow = true;
|
||
|
}
|
||
|
},
|
||
|
onKeyUp(index, e) {
|
||
|
let flag = this.ipAddress.some((item) => {
|
||
|
return item === '';
|
||
|
});
|
||
|
if (flag) {
|
||
|
this.errShow = true;
|
||
|
} else {
|
||
|
this.errShow = false;
|
||
|
}
|
||
|
},
|
||
|
onChange(index, e) {
|
||
|
// console.log(this.defaultValue);
|
||
|
let value = e.target.value;
|
||
|
let ip = this.defaultValue;
|
||
|
value = value.toString().replace(/[^0-9]/g, '');
|
||
|
value = parseInt(value, 10);
|
||
|
if (isNaN(value)) {
|
||
|
value = '';
|
||
|
} else {
|
||
|
value = value < 0 ? 0 : value;
|
||
|
value = value > 255 ? 255 : value;
|
||
|
}
|
||
|
ip[index] = value;
|
||
|
if (ip[index] === '') {
|
||
|
ip[index] = '';
|
||
|
this.activeIndex[index] = true;
|
||
|
} else {
|
||
|
this.activeIndex[index] = false;
|
||
|
}
|
||
|
let ipResult = this.defaultValue.join('.');
|
||
|
this.ipResult = ipResult;
|
||
|
this.$emit('change', this.ipResult);
|
||
|
this.$emit('updata:modelValue', ipResult);
|
||
|
},
|
||
|
},
|
||
|
});
|
||
|
</script>
|
||
|
<style lang="less" scoped>
|
||
|
.active {
|
||
|
border: 1px solid red;
|
||
|
}
|
||
|
|
||
|
input::-webkit-outer-spin-button,
|
||
|
input::-webkit-inner-spin-button {
|
||
|
-webkit-appearance: none;
|
||
|
}
|
||
|
.ipInputContain {
|
||
|
display: flex;
|
||
|
max-width: 298px;
|
||
|
width: 236px;
|
||
|
-webkit-box-sizing: border-box;
|
||
|
box-sizing: border-box;
|
||
|
.ipInputBox {
|
||
|
position: relative;
|
||
|
flex: 1;
|
||
|
margin-right: 10px;
|
||
|
font-family: heiti, Helvetica, Roboto, Arial, sans-serif;
|
||
|
font-size: 14px;
|
||
|
// color: #172e3d;
|
||
|
// overflow: hidden;
|
||
|
// -webkit-font-smoothing: antialiased;
|
||
|
// -moz-osx-font-smoothing: grayscale;
|
||
|
.ipInput {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
outline: none;
|
||
|
padding: 0 5px;
|
||
|
min-width: 40px;
|
||
|
-webkit-box-sizing: border-box;
|
||
|
box-sizing: border-box;
|
||
|
line-height: 30px;
|
||
|
text-align: center;
|
||
|
height: 30px;
|
||
|
// background: inherit;
|
||
|
border-radius: 0;
|
||
|
color: #172e3d;
|
||
|
}
|
||
|
.tips {
|
||
|
position: absolute;
|
||
|
top: 37px;
|
||
|
border: 1px solid #ddd;
|
||
|
background: #d8d8d8;
|
||
|
min-width: 40px;
|
||
|
max-width: 300px;
|
||
|
height: 25px;
|
||
|
box-sizing: border-box;
|
||
|
padding: 3px;
|
||
|
text-align: center;
|
||
|
z-index: 999;
|
||
|
&::before {
|
||
|
content: '';
|
||
|
display: block;
|
||
|
width: 10px;
|
||
|
border: 5px solid transparent;
|
||
|
border-bottom: 5px solid #d8d8d8;
|
||
|
position: absolute;
|
||
|
top: -10px;
|
||
|
left: 50%;
|
||
|
transform: translate(-50%, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.ipInputBox::after {
|
||
|
content: '.';
|
||
|
position: absolute;
|
||
|
top: 12px;
|
||
|
right: -7px;
|
||
|
}
|
||
|
.ipInputBox:nth-child(4):after {
|
||
|
content: '';
|
||
|
}
|
||
|
.errorText {
|
||
|
margin-top: 10px;
|
||
|
color: red;
|
||
|
letter-spacing: 1px;
|
||
|
}
|
||
|
</style>
|