基于 element ui、vue2 的IP输入框 组件

1,089 阅读1分钟
<template>
	<div :class="disabled ? 'disabled' : ''" class="ip_box">
		<el-input
			ref="ip1"
			:disabled="disabled"
			v-model="ip1"
			maxlength="3"
			@input="ip1 = ip1.replace(/[^\d]/g, '')"
			@keyup.native="keyupEvent(1, $event)"
			@blur="syncIp1(), submitIp()"
		/>
		<div class="ip_dot" />
		<el-input
			ref="ip2"
			:disabled="disabled"
			v-model="ip2"
			maxlength="3"
			@input="ip2 = ip2.replace(/[^\d]/g, '')"
			@keyup.native="keyupEvent(2, $event)"
			@blur="syncIp2(), submitIp()"
		/>
		<div class="ip_dot" />
		<el-input
			ref="ip3"
			:disabled="disabled"
			v-model="ip3"
			maxlength="3"
			@input="ip3 = ip3.replace(/[^\d]/g, '')"
			@keyup.native="keyupEvent(3, $event)"
			@blur="syncIp3(), submitIp()"
		/>
		<div class="ip_dot" />
		<el-input
			ref="ip4"
			:disabled="disabled"
			v-model="ip4"
			maxlength="3"
			@input="ip4 = ip4.replace(/[^\d]/g, '')"
			@keyup.native="keyupEvent(4, $event)"
			@blur="syncIp4(), submitIp()"
		/>
	</div>
</template>

<script>
export default {
	name: "IpInput",
	model: {
		prop: "ipAddress",
		event: "change",
	},
	props: {
		ipAddress: {
			type: String,
		},
		disabled: {
			type: Boolean,
			default: false,
		},
	},
	data() {
		return {
			ip1: "",
			ip2: "",
			ip3: "",
			ip4: "",
		};
	},
	watch: {
		ipAddress(val) {
			if (val !== null && val !== "" ) {
				// split()将字符串分割为子字符串数组
				const ipList = val.split(".");
				this.ip1 = ipList[0];
				this.ip2 = ipList[1];
				this.ip3 = ipList[2];
				this.ip4 = ipList[3];
			}
		},
		ip1: {
			handler: function() {
				this.$nextTick(() => {
					if (this.ip1.length === 3) {
						this.$refs.ip2.focus();
					}
				});
			},
		},
		ip2: {
			handler: function() {
				this.$nextTick(() => {
					if (this.ip2.length === 3) {
						this.$refs.ip3.focus();
					}
				});
			},
		},
		ip3: {
			handler: function() {
				this.$nextTick(() => {
					if (this.ip3.length === 3) {
						this.$refs.ip4.focus();
					}
				});
			},
		},
	},
	methods: {
		// 三位数自动跳转,ip超过255设置为255,去掉前面的0
		syncIp1() {
			if (this.ip1 === "") {
				this.ip1 = "";
			} else if (parseInt(this.ip1) > 255) {
				this.ip1 = "255";
				this.$message({
					message: "这不是有效值,请指定一个0-255之间的值",
					type: "error",
				});
			} else if (this.ip1 === "0" || this.ip1 === "00" || this.ip1 === "000") {
				this.ip1 = "0";
			} else {
				this.ip1 = this.ip1.replace(/\b(0+)/g, "");
			}
		},
		syncIp2() {
			if (this.ip2 === "") {
				this.ip2 = "";
			} else if (parseInt(this.ip2) > 255) {
				this.ip2 = "255";
				this.$message({
					message: "这不是有效值,请指定一个0-255之间的值",
					type: "error",
				});
			} else if (this.ip2 === "0" || this.ip2 === "00" || this.ip2 === "000") {
				this.ip2 = "0";
			} else {
				this.ip2 = this.ip2.replace(/\b(0+)/g, "");
			}
		},
		syncIp3() {
			if (this.ip3 === "") {
				this.ip3 = "";
			} else if (parseInt(this.ip3) > 255) {
				this.ip3 = "255";
				this.$message({
					message: "这不是有效值,请指定一个0-255之间的值",
					type: "error",
				});
			} else if (this.ip3 === "0" || this.ip3 === "00" || this.ip3 === "000") {
				this.ip3 = "0";
			} else {
				this.ip3 = this.ip3.replace(/\b(0+)/g, "");
			}
		},
		syncIp4() {
			if (this.ip4 === "") {
				this.ip4 = "";
			} else if (parseInt(this.ip4) > 255) {
				this.ip4 = "255";
				this.$message({
					message: "这不是有效值,请指定一个0-255之间的值",
					type: "error",
				});
			} else if (this.ip4 === "0" || this.ip4 === "00" || this.ip4 === "000") {
				this.ip4 = "0";
			} else {
				this.ip4 = this.ip4.replace(/\b(0+)/g, "");
			}
		},
		// 失去焦点时判断输入是否完成,向父组件传递ip
		submitIp() {
			if (!(this.ip1 === "") && !(this.ip2 === "") && !(this.ip3 === "") && !(this.ip4 === "")) {
				const ipVal = this.ip1 + "." + this.ip2 + "." + this.ip3 + "." + this.ip4;
				this.$emit("change", ipVal);
			} else {
				this.$emit("change", '')
				return;
			}
		},
		// 按下左键和右键焦点左右移动
		keyupEvent(index, e) {
			this.$nextTick(() => {
				// 按下'↑'键焦点左移
				if (e.keyCode === 38) {
					if (index === 2) {
						this.$refs.ip1.focus();
					} else if (index === 3) {
						this.$refs.ip2.focus();
					} else if (index === 4) {
						this.$refs.ip3.focus();
					}
				} else if (e.keyCode === 40) {
					// 按下'↓'键焦点右移
					if (index === 1) {
						this.$refs.ip2.focus();
					} else if (index === 2) {
						this.$refs.ip3.focus();
					} else if (index === 3) {
						this.$refs.ip4.focus();
					}
				}
			});
		},
	},
};
</script>

<style lang="scss" scoped>
.ip_box {
	width: 100%;
	border: 1px solid #dcdfe6;
	border-radius: 5px;
	height: 38px;
	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
	overflow: hidden;
	:deep(.el-input__inner) {
		border: 0 !important;
		padding: 0;
		text-align: center;
	}
	:deep(.el-input) {
		width: 48px;
	}
	&.disabled {
		background-color: #f5f7fa;
		color: #c0c4cc;
		cursor: not-allowed;
	}
}
.ip_dot {
	margin-top: 7px;
	display: inline-block;
	width: 2px;
	height: 2px;
	border-radius: 50%;
	background-color: #606266;
}
.disabled {
	.ip_dot {
		background-color: #c0c4cc;
	}
}
</style>