vue2 web 多标签输入框 elinput是否当前焦点

又来分享一点点工作积累及解决方案

产品中需要用户输入一些文字后按下回车键生成标签来显示在页面上,经过尝试与改造完成如下:

javascript 复制代码
<template>
    <div class="tags-view" @click="beginInput">
        <el-tag :key="index" v-for="(tag, index) in dynamicTags" closable :disable-transitions="false"
            @close="handleClose(index)">
            {{ tag }}
        </el-tag>
        <el-input v-if="inputVisible" class="input-new-tag" style="width: 100%;" v-model="inputValue" ref="saveTagInput"
            size="small" @keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm">
        </el-input>
        <!-- <el-button v-else class="button-new-tag" size="small" @click="showInput">+</el-button> -->
    </div>
</template>

<script>
export default {
    name: 'inputTag',
    props: {
        tags: {
            type: Array,
            default: []
        },
    },
    watch: {
        tags: {
            deep: true,
            immediate: true,
            handler(val) {
                this.dynamicTags = val || []
            }
        }
    },
    data() {
        return {
            dynamicTags: [],
            inputVisible: false,
            inputValue: ''
        };
    },
    methods: {
        handleClose(index) {
            this.dynamicTags.splice(index, 1);
        },
        showInput() {
            this.inputVisible = true;
            this.$nextTick(_ => {
                this.$refs.saveTagInput.$refs.input.focus();
            });
        },
        beginInput() {
            this.showInput();
        },
        handleInputConfirm() {
            let inputValue = this.inputValue;
            if (inputValue) {
                this.dynamicTags.push(inputValue);
            }
            const inputElement = this.$refs.saveTagInput.$refs.input; // 获取input DOM元素
            const isFocused = document.activeElement === inputElement; // 判断是否为当前焦点
            this.inputVisible = isFocused;
            
            this.inputValue = '';
            this.$emit('changed', this.dynamicTags)
        }
    }
}
</script>


<style lang="scss" scoped>
.tags-view {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: wrap;

    min-height: 32px;
    padding: 4px 5px;
    border: 1px solid #DCDFE6;
    border-radius: 4px;
}

.button-new-tag {
    margin-left: 10px;
    height: 24px;
    line-height: 24px;
    padding-top: 0;
    padding-bottom: 0;
}

.input-new-tag {
    height: 24px;
    line-height: 24px;
    width: 90px;
    //margin-left: 10px;
    vertical-align: bottom;
}

::v-deep {
    .el-tag {
        margin-left: 5px;
        margin-top: 2px;
        margin-bottom: 2px;
    }

    .el-input__inner {
        height: 24px;
        line-height: 24px;

        border: none;
        padding: 0px 5px;
    }
}
</style>

组件的使用:

javascript 复制代码
import InputTag from '../components/inputTag.vue'

tags用于默认值的回调,changed事件用于组件数据发生变化时的回调通知。

javascript 复制代码
<InputTag class="w-100" :tags="tagsValue" @changed="tagsChanged"></InputTag>

组件本身也比较简单,没有啥值得去细分和品评的技术点

enter事件和blur事件走了同一个事件,会导致输入不连续,为解决这个问题,我们只需要判断当前input是不是焦点,如果是,则不隐藏输入框即可,如下isFoucsed变量的判断即为是否本身自己是当前焦点的input!

javascript 复制代码
handleInputConfirm() {
    let inputValue = this.inputValue;
    if (inputValue) {
        this.dynamicTags.push(inputValue);
    }
    const inputElement = this.$refs.saveTagInput.$refs.input; // 获取input DOM元素
    const isFocused = document.activeElement === inputElement; // 判断是否为当前焦点
    this.inputVisible = isFocused;
    
    this.inputValue = '';
    this.$emit('changed', this.dynamicTags)
}
相关推荐
JieE21217 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
runnerdancer17 小时前
LLM是怎么处理messages数组的,提示词缓存又是什么
前端·agent
陈随易18 小时前
VSCode的Copilot扩展支持接入DeepSeek,Kimi了!
前端·后端·程序员
我不是外星人20 小时前
有了 Harness Engineering ,真的还需要研发工程师吗?
前端·后端·ai编程
candyTong20 小时前
RTK 技术原理:一次典型会话里,80% 上下文是怎么省下来的
javascript·后端·架构
IT_陈寒1 天前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
Jackson__1 天前
分享一个横向滚动案例,带悬停暂停,通用性很强
前端
MariaH1 天前
git rebase的使用
前端
_柳青杨1 天前
深入理解 JavaScript 事件循环
前端·javascript
阡陌Jony1 天前
关于前端性能优化的一些问题:
前端