Vue Tag list

A small component able to display, add and remove tags.

Made with

Html
Css/scss
JavaScript

html

<app>
  <h3>Complete integration x2</h3>
  <tag-list v-model="initialList"></tag-list>
  <tag-list v-model="initialList"></tag-list>
  <h3>Isolated</h3>
  <tag-list :isolated-taglist="initialList"></tag-list>
  <h3>Blank</h3>
  <tag-list></tag-list>
</app>

Css

// BLUE
$color-base: #9bd;
$color-secondary: #228;
$color-neg: #fff;

// RED
$color-base: #d12929;
$color-secondary: #ffff;
$color-neg: #fff;

body{
  padding: 40px;
  font-family: Verdana, Arial, sans-serif;
}
button{
  cursor:pointer;
}

.tag-list{
  border: 1px solid #aa8;
  margin: 10px;
  padding: 10px;
  ul > * {
    display: inline-block;
  }
}
.tag {
  $t-color: $color-secondary;
  margin: 2px 5px;
  padding: 5px 8px 5px 10px;
  border-radius:5px;
  background-color: $color-base;
  color: $t-color;
  .delete-btn{
    $db-size: 18px;
    $db-color: $color-neg;
    width: $db-size;
    height: $db-size;
    padding: 0 5px 0 4px;
    color: $db-color;
    border: 1px solid $db-color;
    border-radius: 25%;
    background: none;
//    font-size: 1em;
    line-height: $db-size - 6;
  }
}

JavaScript

function cloneArray(arr){
  return arr.reduce(function(agg, val){
    return agg.concat(val);
  }, [])
}

Vue.component('tag-list', {
  name: 'tag-list',
  model:{
    prop:'taglist',
    event:'input'
  },
  props:{
    taglist:{
      type: Array,
      default:undefined
    },
    isolatedTaglist:{
      type: Array,
      default:[]
    }
  },
  data(){
    return {
      tags: this.taglist ? cloneArray(this.taglist) : cloneArray(this.isolatedTaglist),
      tag:''
    }
  },
  methods:{
    addTag(keyValue){
      var savedInput =  ''
      switch(keyValue.key){
        case 'Enter': savedInput = this.tag; break;
        case ' ':
        case ',':
        case ';':
          savedInput = this.tag.substring(0, this.tag.length-1)
          break;
        default:
      }
      if(savedInput!=''){
          this.tags.push(savedInput)
          this.tag = ''
          this.$emit('input', cloneArray(this.tags))
      }
    },
    removeTag(id){
      this.tags.splice(id, 1)
      this.$emit('input', cloneArray(this.tags))
    }
  },
  watch:{
    taglist(taglist){
      this.tags = taglist.reduce(function(agg, val){
        return agg.concat(val);
      }, [])
    }
  },
  template:`
    <div class="tag-list">
      <ul>
        <li class="tag" v-for="(item, key) in tags" :key.number="key">
          <span class="title">{{item}}</span>
          <button class="delete-btn" @click="removeTag(key)">X</button>
        </li>
        <li class="search-box">
          <input type="text" placeholder="Add tag…" v-model="tag" @keyup="addTag">
        </li>
      </ul>
    </div>
  `
})

new Vue({
  el: 'app',
  data(){
    return {
      initialList: ['vuejs','list','ui-element']
    }
  }
})

Demo

See the Pen Vue Tag list by Guillaume Barbier (@gyomb) on CodePen.