Vue .exact modifier test

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<div id="app">
  <div>
    <h2>Desktop using Vue.js 2.5.x </h2>
    <p><strong>Click</strong> a Icon, <strong>Click(+ Ctrl)</strong> Icons, <strong>Click</strong> blank area</p>
    <div class="frame">
      <div class="frame-header">
        <i class="fa fa-folder-o" aria-hidden="true"></i>
        <span>File Explorer</span>
      </div>
      <div class="frame-body" @click="resetSelectedIcons">
        <div class="icons">
          <div class="icon" :class="{ active: isSelected(icon)}" v-for="icon in icons" :key="icon.id" @click.exact.stop="selectIcon(icon)" @click.ctrl.exact.stop="multiSelectIcons(icon)"
@click.meta.exact.stop="multiSelectIcons(icon)">
            <i class="fa fa-5x icon-image" :class="`fa-${icon.image}`"></i>
            <span class="icon-name">{{icon.name}}</span>
          </div>
        </div>
      </div>
      <div class="frame-footer">
        <span>{{ iconCount }}</span>
        <span>{{ selectedIconCount }}</span>
      </div>
    </div>
    <hr>
    <div class="debug">
      <pre>{{selected}}</pre>
    </div>
  </div>
</div>

SCSS

* {
    box-sizing: border-box;
  }
  
  .frame {
    outline: 1px solid #1883d7;
    .frame-header {
      padding: 5px;
      height: 30px;
      outline: 1px solid #ddd;
    }
    .frame-body {
      padding: 5px;
      height: 200px;
      overflow: auto;
    }
    .frame-footer {
      height: 20px;
      outline: 1px solid #ddd;
    }
  }
  
  .icons {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    overflow: auto;
    .icon {
      flex: 1;
      display: flex;
      max-width: 200px;
      align-items: center;
      user-select: none;
      padding: 10px;
      margin: 5px;
      &:hover {
        background-color: rgba(3, 166, 255, 0.3);
      }
      &.active {
        outline: solid rgba(3, 166, 255, 0.9);
        background-color: rgba(3, 166, 255, 0.3);
      }
      .icon-name {
        margin-left: 5px;
      }
    }
  }

JavaScript

new Vue({
  el: '#app',
  mounted: function() {
    this.icons = [{
      id: 1,
      image: 'desktop',
      name: 'My Computer'
    }, {
      id: 2,
      image: 'github',
      name: 'Github'
    }, {
      id: 3,
      image: 'folder-o',
      name: 'Documents'
    }, {
      id: 4,
      image: 'terminal',
      name: 'Terminal'
    }, {
      id: 5,
      image: 'chrome',
      name: 'Chrome'
    }]
    this.selected = [this.icons[1], this.icons[2]]
  },
  data: function() {
    return {
      selected: [],
      icons: []
    }
  },
  computed: {
  	iconCount: function () { 
    	const count = this.icons.length
    	return count < 2 ? `${count} Item` : `${count} Items`
    },
    selectedIconCount: function () {
    	const count = this.selected.length
      if (count === 0) {
      	return ''
			} else if (count === 1) {
      	return '1 Item selected'
      } else {
      	return `${count} Items selected`
			}
    }
  },
  methods: {
    selectIcon: function(clickedIcon) {
      this.selected = [clickedIcon]
    },
    multiSelectIcons: function(clickedIcon) {
      if (this.isSelected(clickedIcon)) {
        const index = this.selected.indexOf(clickedIcon)
        this.selected.splice(index, 1)
      } else {
        this.selected.push(clickedIcon)
      }
    },
    resetSelectedIcons: function() {
      this.selected = []
    },
    isSelected: function(icon) {
      return this.selected.includes(icon)
    }
  }
})