用vue寫IP地址文本框組件

前言

實現原理是用4個文本框拼到一起,中間加一個點樣式,再加上對於內容的限制爲0-255,再加上光標位置的判斷即可。

具體內容

  1. 在該目錄下創建組件文件
    在這裏插入圖片描述
    文件內容如下
<template>
    <ul class="ipAdress">
        <li v-for="(item,index) in ipAddress">
            <input ref="ipInput" v-model="item.value" type="text" class="ipInputClass" @input="checkIpVal(item)" @keyup="turnIpPosition(item,index,$event)"/>
            <div></div>
        </li>
    </ul>
</template>

<script>
export default {
    props: {
        value: {
            type: String,
            default: ''
        }
    },
    data() {
        return {
            ipAddress: [
                {
                    value: ''
                },{
                    value: ''
                },{
                    value: ''
                },{
                    value: ''
                }
            ]
        }
    },
    watch: {
        ipAddress: { // 雙向數據綁定的value
            handler: function (newVal, oldVal) {
                let str = ''
                for (const i in this.ipAddress) {
                    str += this.formatter(this.ipAddress[i].value)
                }
                if (str === '000000000000') {
                    str = ''
                }
                this.$emit('input', str)
            },
            deep: true
        }
    },
    methods: {
        // 格式化補零方法
        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
            let 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();
                }
            }
        }
    }
}
</script>
<style type="text/css" scoped>
    .ipAdress{
        display: flex;
        border: 1px solid #dcdfe6;
        border-radius: 4px;
        width: 196px;
        height: 36px;
        padding-inline-start: 0px;
    }
    .ipAdress li{
        position: relative;
        height: 36px;
        margin: 0;
        list-style-type: none;
    }
    .ipInputClass{
        border: none;
        width: 49px;
        height: 23px;
        text-align: center;
        background: transparent;
    }
    .ipAdress li div{
        position: absolute;
        bottom: 8px;
        right: 0;
        border-radius: 50%;
        background: #505050;
        width: 2px;
        height: 2px;
    }
    /*只需要3個div*/
    .ipAdress li:last-child div{
        display: none;
    }
    /*取消掉默認的input focus狀態*/
    .ipAdress input:focus{
        outline: none;
    }
</style>

2.具體用法
先引入組件
先引入組件
然後如下使用
在這裏插入圖片描述
3.效果
在這裏插入圖片描述

後記

具體使用中根據項目樣式風格調調樣式,改改方法就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章