首页 技术 正文
技术 2022年11月17日
0 收藏 705 点赞 4,030 浏览 2969 个字

简介

TagsInput 是一种可编辑的输入框,通过回车或者分号来分割每个标签,用回退键删除上一个标签。用 vue 来实现还是比较简单的。

先看效果图,下面会一步一步实现他。

  • 注:以下代码需要vue-cli环境才能执行

(一)伪造一个输入框

因为单行的文本框只能展示纯文本,所以图里面的标签实际上都是 html元素,用vue模板来写的话,是这样的:

<template>
<div class="muli-tags" @click='focus'>
<button class='btn' v-for='(tag, index) in tags' :key='index'>
{{tag}}
</button>
<input type="text" ref='input' v-model='current'>
</div>
</template><script>
export default {
name: 'TagsInput',
methods: {
focus () {
this.$refs.input.focus()
},
},
data () {
return {
tags: [],
current: ''
}
}
}
</script><style lang='less'>
.muli-tags{
padding: 5px 10px;
display: block;
border: 1px solid #ccc;
input{
background: transparent;
}
}
.btn{
margin: 0 5px 3px 0;
padding: 4px 5px;
background: #fff;
border: 1px solid #eee;
box-shadow: 0 0 4px;
}
</style>

(二)监听输入

在伪造好一个输入框之后,我们对输入框的事件进行处理,

  • 回车和逗号会把input的值添加到tags数组,然后清空input
  • 添加值之前,判断tags数组是否已经包含同名的值
  • 按回退键,删除最近的一个标签
// @keydown.188   188代表是是分号键的keyCode
<input type="text"
ref='input'
@keyup.enter="add"
@keydown.delete="del"
@keydown.188='split'
v-model='current'>methods: {
// 按下分号键的时候,需要阻止默认事件,否则会出现分号
split (e) {
e.preventDefault()
this.add(e)
},
add (e) {
const val = e.target.value
if (!val) return
// 如果已经存在相同tag,不再添加
if (this.tags.indexOf(val) > -1) return
// 把输入值添加到tag,并清空文本框
this.tags.push(val)
this.current = ''
},
del (e) {
// 当文本框内没有值,再按回退键,则删除最后一个tag
if (!e.target.value.length) {
this.tags.pop()
}
},
}

(三)删除标签

前面都是通过键盘来操作标签,鼠标点击标签应该也是可以删除的

<button class='btn' v-for='(tag, index) in tags' :key='index' @click='delTag(index)'>{{tag}} <span>x</span></button>methods: {
// 删除点击的标签
delTag (index) {
this.tags.splice(index, 1)
}
}

(四)自定义 v-model

通过上面的步骤,一个 tagsinput 组件就已经做好了,再给他添加自定义的 v-model ,让他可以像input一样响应表单数据。

  // props
props: {
value: Array,
required: true,
default: () => []
} // computed
computed: {
tags () {
return this.value.slice()
}
} // methods
methods: {
// 删除点击的标签
delTag (index) {
this.tags.splice(index, 1)
this.$emit('input', this.tags)
}
}

(五)完整代码

// TagsInput.vue
<template>
<div class="muli-tags" @click='focus'>
<button class='btn' v-for='(tag, index) in tags' :key='index' @click='delTag(index)'>{{tag}} <span>x</span></button>
<input type="text"
ref='input'
@keyup.enter="add"
@keydown.delete="del"
@keydown.188='split'
v-model='current'>
</div>
</template><script>
export default {
props: {
value: Array,
required: true,
default: () => []
},
methods: {
focus () {
this.$refs.input.focus()
},
split (e) {
e.preventDefault()
this.add(e)
},
add (e) {
const val = e.target.value
if (!val) return
if (this.tags.indexOf(val) > -1) return
this.tags.push(val)
this.$emit('input', this.tags)
this.current = ''
},
del (e) {
if (!e.target.value.length) {
this.tags.pop()
this.$emit('input', this.tags)
}
},
delTag (index) {
this.tags.splice(index, 1)
this.$emit('input', this.tags)
}
},
computed: {
tags () {
return this.value.slice()
}
},
data () {
return {
current: ''
}
}
}
</script><style lang='less'>
.muli-tags{
padding: 5px 10px;
display: block;
border: 1px solid #ccc;
input{
background: transparent;
}
.btn{
margin: 0 5px 3px 0;
padding: 4px 5px;
background: #fff;
border: 1px solid #eee;
box-shadow: 0 0 4px;
}
}
</style>

作为组件被调用,这样就可以看到像文章开头那幅图一样的组件了。

// 父组件
<template>
<tags-input v-model='tags'/>
</template>
<script>
import TagsInput from './TagsInput.vue'
export default {
components: {
TagsInput
},
data () {
return {
tags: ['tag1', 'tag2', 'tag3']
}
}
}
</script>
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,581
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918