vue组件系列之TagsInput详解


Posted in Javascript onMay 14, 2020

简介

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

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

vue组件系列之TagsInput详解

注:以下代码需要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>

总结

到此这篇关于vue组件TagsInput的文章就介绍到这了,更多相关vue组件TagsInput内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript实现的鼠标链接提示效果生成器代码
Jun 28 Javascript
JObj预览一个JS的框架
Mar 13 Javascript
在jQuery中 常用的选择器介绍
Apr 16 Javascript
js实现图片旋转的三种方法
Apr 10 Javascript
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
Mar 21 jQuery
vue cli 3.0 使用全过程解析
Jun 14 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
Apr 13 Javascript
深入浅析vue-cli@3.0 使用及配置说明
May 08 Javascript
vue使用微信JS-SDK实现分享功能
Aug 23 Javascript
js实现无限瀑布流实例方法
Sep 16 Javascript
小程序如何自主实现拦截器的示例代码
Nov 04 Javascript
vue路由守卫,限制前端页面访问权限的例子
Nov 11 Javascript
ant-design-vue按需加载的坑的解决
May 14 #Javascript
JavaScript数组排序功能简单实现
May 14 #Javascript
Typescript3.9 常用新特性一览(推荐)
May 14 #Javascript
Node.js API详解之 Error模块用法实例分析
May 14 #Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
May 14 #Javascript
JavaScript, select标签元素左右移动功能实现
May 14 #Javascript
vue实现商品列表的添加删除实例讲解
May 14 #Javascript
You might like
PHP数据库操作面向对象的优点
2006/10/09 PHP
PHP中防止SQL注入实现代码
2011/02/19 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
2013/06/24 PHP
PHP实现批量删除(封装)
2017/04/28 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
php模式设计之观察者模式应用实例分析
2019/09/25 PHP
在Laravel中使用GuzzleHttp调用第三方服务的API接口代码
2019/10/15 PHP
JS效率个人经验谈(8-15更新),加入range技巧
2007/01/09 Javascript
jQuery 源码分析笔记(5) jQuery.support
2011/06/19 Javascript
jquery选择器的选择使用及性能介绍
2013/01/16 Javascript
js获取本机的外网/广域网ip地址完整源码
2013/08/12 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
2015/08/31 Javascript
jQuery zclip插件实现跨浏览器复制功能
2015/11/02 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
jQuery.Validate表单验证插件的使用示例详解
2017/01/04 Javascript
在node.js中怎么屏蔽掉favicon.ico的请求
2017/03/01 Javascript
基于node.js之调试器详解
2017/08/22 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
jQuery获取所有父级元素及同级元素及子元素的方法(推荐)
2018/01/21 jQuery
使用PreloadJS加载图片资源的基础方法详解
2020/02/03 Javascript
[01:50:49]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第三场 1月24日
2021/03/11 DOTA
使用PyCharm配合部署Python的Django框架的配置纪实
2015/11/19 Python
Python编程实现粒子群算法(PSO)详解
2017/11/13 Python
用TensorFlow实现戴明回归算法的示例
2018/05/02 Python
基于Python实现扑克牌面试题
2019/12/11 Python
一文了解python 3 字符串格式化 F-string 用法
2020/03/04 Python
python图片指定区域替换img.paste函数的使用
2020/04/09 Python
css和css3弹性盒模型实现元素宽度(高度)自适应
2019/05/15 HTML / CSS
HTML5自定义mp3播放器源码
2020/01/06 HTML / CSS
屈臣氏越南官网:Watsons越南
2021/01/14 全球购物
幼儿园辞职书
2015/02/26 职场文书
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫
Python接口自动化之文件上传/下载接口详解
2022/04/05 Python
python中redis包操作数据库的教程
2022/04/19 Python
JS前端宏任务微任务及Event Loop使用详解
2022/07/23 Javascript