1. 引言
标签化的输入框在许多前端开发中是非常常见的一个需求,它可以让用户更快速的输入或选择特定的选项。Vue 作为目前流行的前端框架之一,我们可以使用它的组件化思想来实现一个带标签的输入框。
2. 简单的标签化输入框
2.1 创建组件
首先,我们需要创建一个 Vue 组件。我们可以在 Vue.js 官方文档中找到组件的详细用法。下面是一个最简单的标签化输入框组件的代码:
Vue.component('tag-input', {
template: `
<div class="tag-input">
<input v-model="inputValue" @keyup.enter="addTag" />
<div v-for="tag in tags" :key="tag" class="tag">{{ tag }}</div>
</div>
`,
data() {
return {
inputValue: '',
tags: []
}
},
methods: {
addTag() {
if (this.inputValue && !this.tags.includes(this.inputValue)) {
this.tags.push(this.inputValue);
this.inputValue = '';
}
}
}
});
这里我们创建了一个名为 tag-input 的组件,它包含一个 input 元素和一个 div 元素,这个 div 元素用于展示用户添加的标签。
2.2 实现标签添加功能
我们需要在 input 元素中实现输入完成后添加标签的功能。我们可以使用 v-model 指令来实时响应 input 元素的内容,使用 @keyup.enter 事件来响应用户按下 enter 键添加标签。在 addTag 方法中,我们判断用户输入的值是否为空或者重复,并将它添加到 tags 数组中,添加完毕后清空 input 的值。
我们的基础标签化输入框组件已经实现了,现在我们可以在页面中使用这个组件,并进行测试:
<div id="app">
<tag-input></tag-input>
</div>
new Vue({
el: '#app'
});
现在我们可以访问页面,尝试在 input 中输入标签,按下 enter 键确认,可以看到输入的标签实时的追加在输入框下方。
3. 支持标签删除功能
我们已经实现了一个最基础的标签化输入框组件,但是现在无法删除已经添加的标签,这会给用户带来不方便的使用体验。下面,我们将添加标签删除功能。
3.1 修改标签显示方式
为了支持标签删除,我们需要对已经添加的标签的展示方式进行修改。我们使用一个 span 元素来显示标签,并为每个标签添加一个删除按钮,代码如下:
Vue.component('tag-input', {
template: `
<div class="tag-input">
<input v-model="inputValue" @keyup.enter="addTag" />
<span v-for="(tag, index) in tags" :key="tag" class="tag">
{{ tag }}
<span class="remove-tag" @click="removeTag(index)">x</span>
</span>
</div>
`,
data() {
return {
inputValue: '',
tags: []
}
},
methods: {
addTag() {
if (this.inputValue && !this.tags.includes(this.inputValue)) {
this.tags.push(this.inputValue);
this.inputValue = '';
}
},
removeTag(index) {
this.tags.splice(index, 1);
}
}
});
我们为每个标签添加了一个 span 元素,里面包含标签名和移除按钮。当用户点击移除按钮时,我们可以通过 index 参数获取当前点击的标签在数组中的下标,然后使用数组的 splice 方法将它从数组中删除。
3.2 样式调整
当我们添加了标签删除功能后,标签显示的样式会发生一些变化,需要稍加调整。下面是一个简单的 CSS 样式:
.tag-input {
display: flex;
flex-wrap: wrap;
padding: 10px;
border: 1px solid #ccc;
}
.tag {
display: inline-block;
margin: 5px;
background-color: #f5f5f5;
padding: 5px;
border-radius: 3px;
font-size: 14px;
}
.remove-tag {
padding-left: 5px;
cursor: pointer;
}
通过以上 CSS 样式的调整,我们可以使标签化输入框看起来更加美观和舒适。
4. 使用带提示的标签化输入框
除了基本的标签化输入框之外,有时候我们需要提供给用户一些可选的标签,让用户可以从中选取已有的标签。这就需要实现一个带提示的标签化输入框。下面是我们实现带提示的标签化输入框的代码。
4.1 显示可选标签和选项列表
我们需要实现两个能力:一是在用户输入的时候,动态更新可选标签列表;二是在 input 框聚焦或者用户开始输入的时候,展示可选标签列表。为此,我们需要添加一个新的方法,getOptions,这个方法将返回当前可选的标签,并将其动态渲染到页面上。
Vue.component('tag-input', {
template: `
<div class="tag-input" ref="tagInput">
<input v-model="inputValue" @focus="suggest" @keyup.enter="addTag" @keydown.up="arrowUp" @keydown.down="arrowDown" @keyup.esc="unSuggest" />
<div v-for="(tag, index) in tags" :key="tag" class="tag">
{{ tag }}
<span class="remove-tag" @click="removeTag(index)">x</span>
</div>
<div v-show="suggestedOptions.length" class="options">
<li v-for="(option, index) in suggestedOptions" :key="index" @click="choose(index)" :class="{ active: index === activeIndex }">{{ option }}
</div>
</div>
`,
data() {
return {
inputValue: '',
tags: [],
options: ['HTML', 'CSS', 'JavaScript', 'Vue', 'React', 'Angular'],
suggestedOptions: [],
activeIndex: -1
}
},
methods: {
addTag() {
if (this.inputValue && !this.tags.includes(this.inputValue)) {
this.tags.push(this.inputValue);
this.inputValue = '';
}
},
removeTag(index) {
this.tags.splice(index, 1);
},
suggest() {
this.suggestedOptions = this.getOptions();
},
unSuggest() {
this.suggestedOptions = [];
},
choose(index) {
this.inputValue = this.suggestedOptions[index];
this.suggestedOptions = [];
this.addTag();
},
getOptions() {
const options = this.options;
const value = this.inputValue.toLowerCase();
return options.filter(option => option.toLowerCase().startsWith(value) && !this.tags.includes(option));
},
arrowUp() {
if (this.activeIndex > 0) {
this.activeIndex--;
}
},
arrowDown() {
if (this.activeIndex < this.suggestedOptions.length - 1) {
this.activeIndex++;
}
}
}
});
在以上代码中,我们添加了 input 元素的 focus 事件,将输入框的 ref 设为 tagInput,获取当前可选的标签,并动态更新 suggestedOptions 的值。当 suggestedOptions 不为空时,我们可以将它进行渲染,用户可以选择已有的标签或者继续输入新的标签。
在这个代码中,我们依旧使用了之前的 addTag 和 removeTag 方法来实现新标签的添加和已有标签的删除,但是现在,当用户选择已有标签时,我们需要通过 choose 方法将选中的标签添加到输入框内。如果用户输入的内容没有匹配到标签,我们不会进行提示操作,而是关闭提示框。
4.2 调整样式
我们需要调整样式来适应带提示的标签化输入框,下面是弹出提示框及其选项列表的样式:
.options {
position: absolute;
z-index: 10;
background-color: #fff;
width: 100%;
box-shadow: 0px 0px 5px #ccc;
margin-top: 2px;
}
.options ul {
margin: 0;
padding: 0;
list-style: none;
max-height: 200px;
overflow-y: auto;
}
.options li {
padding: 5px 10px;
cursor: pointer;
}
.options li.active {
background-color: #f5f5f5;
}
现在,我们已经实现了一个功能完善、样式美观的带提示标签化输入框,用户可以在输入框中快速选择或添加标签。
5. 总结
我们在本文中使用了 Vue.js 以及组件化思想,实现了一个功能完善、美观大方的带标签、带提示的输入框。Vue.js 的组件化开发思想,可以让我们高效、灵活的进行前端开发。