vue組件系列-Tags input

前言

最近作後臺系統的組件化開發,藉機和@二胖手同窗一塊兒開發了一個基於vue的開源組件庫,方便後期使用,目前該項目正在持續開發中。php

介紹

你們可能遇到過一種需求,讓用戶輸入以某個特殊字符分隔的字符串,如java,php就是以西文逗號分隔,這種輸入須要用戶自行添加內容之間的特殊分隔符,其實徹底能夠換用一種用戶體驗更好的方式解決。
不知道你們管下面這種叫什麼,我稱之爲Tags input。
demo
其實,當你們在SF寫文章的時候就會有這類標籤選擇框。體驗地址css

實現

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自身決定,會根據內容自動撐開。html

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)">&times;</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

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中的是通過我處理的用於展現的數據,爲每一個標籤添加隨機的背景色。java

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的方法分爲兩種,兩種的處理狀況略有不一樣要加以判斷。git

使用

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-stylegithub

相關文章
相關標籤/搜索