前言
最近做后台系统的组件化开发,借机和@二胖手同学一起开发了一个基于vue的开源组件库,方便后期使用,目前该项目正在持续开发中。
介绍
大家可能遇到过一种需求,让用户输入以某个特殊字符分隔的字符串,如java,php
就是以西文逗号分隔,这种输入需要用户自行添加内容之间的特殊分隔符,其实完全可以换用一种用户体验更好的方式解决。
不知道大家管下面这种叫什么,我称之为Tags input。
其实,当大家在SF写文章的时候就会有这类标签选择框。体验地址
实现
scss
//输入框tags
.tags-wrap{
width: 100%;
height: 100%;
outline: none;
&::after{
content: "";
display: block;
height: 0;
clear: both;
}
}
.tags, .tags-input{
position: relative;
float: left;
color: #fff;
line-height: 28px;
margin: 0 4px 4px 0;
padding: 0 22px 0 10px;
border-radius: 6px;
.content{
line-height: 28px;
}
.del{
width: 22px;
height: 28px;
text-align: center;
cursor: pointer;
position: absolute;
top: -1px;
right: 0;
}
}
.tags-input{
font-size: 14px;
padding: 0;
background-color: inherit;
border: none;
color: inherit;
width: 10em;
}
整个Tags input输入框的宽度由组件的父元素决定,高度由Tags自身决定,会根据内容自动撑开。
vue组件
vue template
<div class="input tags-wrap">
<div class="tags" transition="tags" :style="{backgroundColor: bgc[item.bgc_no]}" v-for="item in dis_source">
<span class="content">{{item.text}}</span><span class="del" @click="del($index, false)">×</span>
</div>
<input class="tags-input" type="text" placeholder="标签,按 enter 创建" v-model="text" @keyup.enter="add(text)" @keydown.delete="del(source.length - 1, true)">
</div>
v-for
是vue的遍历数组方法,:style
用来绑定样式,@click
和@keyup
这些都是绑定事件的语法。
vue data
props: {
source: {
type: Array,
default: []
}
},
data() {
var dis_source = []
this.source.forEach(function (item) {
var obj = {
text: item,
bgc_no: Math.ceil(Math.random() * 10) - 1
}
dis_source.push(obj)
})
return {
text: '',
bgc: ['#e961b4', '#ed664b', '#7b6ac7', '#56abd1', '#f7af4c', '#fe5467', '#52c7bd', '#a479b7', '#cb81ce', '#5eabc5'],
dis_source: dis_source
}
}
数据有两部分,props
来源于父组件,用于同步父子组件的内容,data
中的是经过我处理的用于展示的数据,为每个标签添加随机的背景色。
vue methods
add(text){
if(text != ''){
var count = this.source.length
this.source.$set(count, text)
this.dis_source.$set(count, {
text: text,
bgc_no: Math.ceil(Math.random() * 10) - 1
})
this.text = ''
}
},
del(index, way){
if(way){
if(index >=0 && this.text == ''){
this.source.splice(index, 1)
this.dis_source.splice(index, 1)
}
}else {
this.source.splice(index, 1)
this.dis_source.splice(index, 1)
}
}
就这个组件而言只需要增加/删除tags两个方法,我在模版中删除tags的方法分为两种,两种的处理情况略有不同要加以判断。
使用
html:
<div id="app">
<v-tags :source.sync="source"></v-tags>
</div>
js:
var app = new Vue({
el: '#app',
data: {
source: ['英雄联盟', '骚猪', '对对对对对我是娇妹', '小轩在不在']
},
components: {
'v-tags': tags
}
})
使用时只要把vue和我的组件引入,就可以在页面中使用自定义的v-tags
标签,同时把数据传给子组件并且加上.sync
保持数据与子组件同步。在该组件中,用户可以在标签框中输入内容后按下enter
即可添加新标签,使用delete
删除处于末尾的标签,或者也可以点击标签后面的叉叉删除标签。
除了这个组件之外,我们还开源了其他组件,并且在逐步完善组件库,其他组件也会有系列文章推出,欢迎关注我和@二胖手的专栏,提出意见,或者你期望增加的组件,项目地址:web-style