vue2 web 多标签输入框 elinput是否当前焦点
又来分享一点点工作积累及解决方案
产品中需要用户输入一些文字后按下回车键生成标签来显示在页面上,经过尝试与改造完成如下:
<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>
组件的使用:
import InputTag from '../components/inputTag.vue'
tags用于默认值的回调,changed事件用于组件数据发生变化时的回调通知。
<InputTag class="w-100" :tags="tagsValue" @changed="tagsChanged"></InputTag>
组件本身也比较简单,没有啥值得去细分和品评的技术点
enter事件和blur事件走了同一个事件,会导致输入不连续,为解决这个问题,我们只需要判断当前input是不是焦点,如果是,则不隐藏输入框即可,如下isFoucsed变量的判断即为是否本身自己是当前焦点的input!
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) }