1.实列图片
2.代码部分
<template>
<div class="ami-input-ip">
<ul class="ipAdress" :class="[actived]" @mouseover="changeColor()">
<li v-for="(item,index) in ipAddress" :key="index">
<ami-input class="ipInputClass"
ref="ipInput"
type="text"
:size="size"
v-model="item.value"
v-bind="$attrs"
:disabled="disabled"
:readonly="readonly"
@input="checkIpVal(item)"
@keyup="turnIpPosition(item,index,$event)"
/>
<div class="ip-box"></div>
</li>
</ul>
<div class="icon" v-if="this.clearable&&this.readonly!==true">
<i class="ami-icon-circle-close" @click="clear()"></i>
</div>
</div>
</template>
<script>
export default {
name: 'AmiInputIp',
props: {
size: {
type: String,
default: 'large'
},
// 侦听的值
value: {
type: String,
default: ''
},
// 设置返回值类型
formatStyle: {
type: String,
default: 'node'
},
// 禁用
disabled: {
type: Boolean,
default: false
},
// 是否只读
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
actived: '',
clearable: false,
ipAddress: [{value: ''}, {value: ''}, {value: ''}, {value: ''}]
};
},
mounted() {
if (this.value && this.value.length > 0 && this.value.split('.').length === 4) {
var arr = this.value.split('.');
for (var i in arr) {
this.ipAddress[i].value = arr[i];
}
}
},
watch: {
// 双向数据绑定的value
ipAddress: {
handler(newVal, oldVal) {
let str = '';
for (const i in this.ipAddress) {
if (this.formatStyle === 'noNode') {
str += this.formatter(this.ipAddress[i].value);
} else {
if (str.length > 0) {
str += '.';
}
str += this.ipAddress[i].value === '' ? '000' : this.ipAddress[i].value;
}
}
if (str === '000000000000' || str === '000.000.000.000') {
str = '';
}
// 判断输入框是有值
this.clearable = str.length > 0;
this.$emit('input', str);
},
deep: true
}
},
methods: {
// 清空
clear() {
for (var i in this.ipAddress) {
this.ipAddress[i].value = '';
}
},
// 格式化补零
formatter(val) {
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;
},
// 检查ip输入是否为0-255
checkIpVal(item) {
// 确保每个值都处于0-255
var 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;
},
// 光标位置判断
turnIpPosition(item, index, event) {
let self = this;
let e = event || window.event;
if (e.keyCode === 37) {
// 左箭头向左跳转,左一不做任何措施
if (index !== 0 && e.currentTarget.selectionStart === 0) {
self.$refs.ipInput[index - 1].focus();
}
} else if (e.keyCode === 39) {
// 右箭头向右跳转,右一不做任何措施
if (index !== 3 && e.currentTarget.selectionStart === item.value.toString().length) {
self.$refs.ipInput[index + 1].focus();
}
} else if (e.keyCode === 8) {
// 删除键把当前数据删除完毕后会跳转到前一个input,左一不做任何处理
if (index !== 0 && item.value === '') {
self.$refs.ipInput[index - 1].focus();
}
} else if (e.keyCode === 13 || e.keyCode === 32 || e.keyCode === 190) {
// 回车键、空格键、冒号均向右跳转,右一不做任何措施
if (index !== 3) {
self.$refs.ipInput[index + 1].focus();
}
} else if (item.value.toString().length === 3) {
// 满3位,光标自动向下一个文本框
if (index !== 3) {
self.$refs.ipInput[index + 1].focus();
}
}
},
// 鼠标移入事件
changeColor() {
// 判断是否禁用(是否为已读),来显示边框
if (this.disabled === false && this.readonly !== true) {
this.actived = this.actived === 'actived' ? '' : 'actived';
} else {
this.actived = '';
}
}
}
};
</script>
<style>
.ami-input-ip{
position: relative;
width: 100%;
.ipAdress{
display: flex;
border: 1px solid #dcdfe6;
border-radius: 9px;
padding-inline-start: 0px;
//transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
li{
position: relative;
list-style-type: none;
//表格样式
.ipInputClass{
.ami-input__inner{
border: 0;
width: 100%;
padding: 0 10px;
text-align: center;
background: transparent;
}
}
.ip-box{
position: absolute;
bottom: 8px;
right: 0;
border-radius: 50%;
background: #505050;
width: 2px;
height: 2px;
}
}
// 第三个点隐藏
:last-child .ip-box{
display: none;
}
}
// 图标清空
.icon{
position:absolute;
right: 3px;
top:30%;
font-size: 14px;
}
.actived{
border: 1px solid $--input-focus-border;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
</style>
3.说明文档
InputIp ip输入框
通过键盘输入ipv4地址。无法输入英文,数字大于255的自动转换
基础用法
v-model
通过v-model来绑定数据
:::demo v-model
通过v-model来绑定数据
<div style="width: 240px;">
<ami-input-ip v-model="inputIp"></ami-input-ip>
</div>
<script>
export default {
data(){
return{
inputIp:"192.168.1.3"
}
}
}
</script>
:::
禁用状态
通过 disabled
属性指定是否禁用 ami-input-ip 组件
:::demo 通过 disabled
属性指定是否禁用 ami-input-ip 组件
<div style="width: 240px;">
<ami-input-ip v-model="inputIp" disabled></ami-input-ip>
</div>
<script>
export default {
data(){
return{
inputIp:""
}
}
}
</script>
:::
只读
使用readonly
属性即可得到一个只读的输入框
:::demo 使用readonly
属性即可得到一个只读的输入框
<div style="width: 240px;">
<ami-input-ip v-model="inputIp" readonly></ami-input-ip>
</div>
<script>
export default {
data(){
return{
inputIp:"192.168.0.1"
}
}
}
</script>
:::
尺寸
使用size
属性即可控制输入框的大小, 支持输入默认和large
、small
、mini
.
:::demo 使用size
属性即可控制输入框的大小, 支持输入默认和large
、small
、mini
.
<div style="width: 240px;">
<ami-input-ip v-model="inputIp" size="large"></ami-input-ip>
</div>
<div style="width: 240px;">
<ami-input-ip v-model="inputIp" size="small"></ami-input-ip>
</div>
<div style="width: 240px;">
<ami-input-ip v-model="inputIp" size="mini"></ami-input-ip>
</div>
<script>
export default {
data(){
return{
inputIp:"192.168.0.1"
}
}
}
</script>
:::
返回格式
使用formatStyle
属性即可控制返回值的格式, 支持输入node
、noNod
e, 默认为node
。node
返回格式为xxx.xxx.xxx.xxx
, noNode
返回格式为xxxxxxxxxxxx
此格式不足字符用0填充。
:::demo
<div style="width: 240px">
<ami-input-ip v-model="inputip"></ami-input-ip>
</div>
<span>返回值为:{{inputip}}</span>
<div style="width: 240px;margin-top:20px;">
<ami-input-ip v-model="ipNoNode" :formatStyle="'noNode'"></ami-input-ip>
<span>返回值为:{{ipNoNode}}</span>
</div>
<script>
export default {
data(){
return{
inputip: '',
ipNoNode: ''
}
}
}
</script>
:::
Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
v-model | 双向绑定(绑定数据) | String | — | 空 |
disabled | 禁用(是否禁止编辑) | Boolean | true / false | false |
readonly | 只读 | boolean | true / false | false |
size | 输入框尺寸 | String | large / small / mini | — |
formatStyle | 设置返回值类型 | String | node / noNode | node |
Input Events
事件说明 | 说明 | 回调参数 |
---|---|---|
clear | 在点击由 clearable 属性生成的清空按钮时触发(默认选中) | —— |