<!-- @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>