vue组件系列之TagsInput详解
简介
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;
input框禁止输入border: 1px solid #eee;
box-shadow: 0 0 4px;
}
</style>
(⼆)监听输⼊
在伪造好⼀个输⼊框之后,我们对输⼊框的事件进⾏处理,
回车和逗号会把input的值添加到tags数组,然后清空input
添加值之前,判断tags数组是否已经包含同名的值
按回退键,删除最近的⼀个标签
// @keydown.188 188代表是是分号键的keyCode
<input type="text"
ref='input'
@="add"
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'
@="add"
</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>
总结
到此这篇关于vue组件TagsInput的⽂章就介绍到这了,更多相关vue组件TagsInput内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论