input回退消失 vue_vue组件--TagsInput

简介

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

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

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

(一)伪造一个输入框

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

{{tag}}

export default {

name: 'TagsInput',

methods: {

focus () {

this.$refs.input.focus()

},

},

data () {

return {

tags: [],

current: ''

}

}

}

.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;

}

(二)监听输入

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

回车和逗号会把input的值添加到tags数组,然后清空input

添加值之前,判断tags数组是否已经包含同名的值

按回退键,删除最近的一个标签

// @keydown.188 188代表是是分号键的keyCode

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()

}

},

}

(三)删除标签

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

{{tag}} x

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

{{tag}} x

ref='input'

@keyup.enter="add"

@keydown.delete="del"

@keydown.188='split'

v-model='current'>

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: ''

}

}

}

.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;

}

}

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

// 父组件

import TagsInput from './TagsInput.vue'

export default {

components: {

TagsInput

},

data () {

return {

tags: ['tag1', 'tag2', 'tag3']

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值