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)
}
相关推荐
2301_7951685841 分钟前
javascript基础从小白到高手系列一十二:JSON
javascript·udp·json
LCG元2 小时前
Vue.js组件开发-如何实现路由懒加载
vue.js
m0_672449602 小时前
基础vue3前端登陆注册界面以及主页面设计
前端·vue.js·elementui
匹马夕阳2 小时前
Vue3中使用组合式API通过路由传值详解
前端·javascript·vue.js
zpjing~.~2 小时前
VUE中css样式scope和deep
前端·css·vue.js
fxshy2 小时前
Vue3父子组件双向绑定值用例
前端·javascript·vue.js
LCG元2 小时前
Vue.js组件开发-如何实现表头搜索
vue.js
风茫2 小时前
如何在vue中渲染markdown内容?
前端·javascript·vue.js
蓝黑20203 小时前
从Vant图标的CSS文件提取图标文件
前端·css·python·vant
勤劳的进取家3 小时前
XML、HTML 和 JSON 的区别与联系
前端·python·算法