Vue Simple Component

HTML

<div id="app">
  <div class="card" v-for="item in items">
    <div class="card__name">{{ item.name }}</div>
    <vue-select v-model="item.selected" :options="item.versions" @input="onCardChanged"></vue-select>
  </div>
</div>

<template id="vue-select">
  <div class="vue-select">
    <div class="vue-select__trigger" @click="toggle">
      {{ value ? value.name || value : 'Select version' }}
    </div>

    <div class="vue-select__menu" v-show="isOpen">
      <div
        class="vue-select__item"
        @click="select(option)"
        v-for="option in options"
      >{{ option.name }}</div>
    </div>
  </div>
</template>

SCSS

.vue-select {
  margin: 8px;
  padding: 8px;

  &__menu {
    background-color: #fff;
  }

  &__trigger {
    cursor: pointer;
    background-color: #ccc;
    border-radius: 3px;
  }

  &__item {
    cursor: pointer;
    padding: 8px;

    &--disabled {
      opacity: 0.5;
    }

    &:hover {
      background-color: #ccc;
    }

    &:last-child {
      border-radius: 0 0 3px 3px;
    }
  }
}

.card {
  border: 1px solid red;
  margin-bottom: 8px;

  &__name {
    margin: 8px;
    padding: 8px;
  }
}

Babel + JSX

Vue.component('vue-select', {
  template: '#vue-select',
  props: {
    selected: {
      default() {
        return null;
      }
    },
    options: {
      type: Array,
      default() {
        return [];
      },
    },
    value: {
      type: [Object, String, Number],
    },
  },
  data() {
    return {
      isOpen: false
    };
  },
  mounted() {
    document.addEventListener('click', this.handleClickOutside, true);
  },
  beforeDestroy() {
    document.removeEventListener('click', this.handleClickOutside, true);
  },
  methods: {
    select(option) {
      this.$emit('input', option);
      this.close();
    },
    toggle() {
      this.isOpen = !this.isOpen;
    },
    open() {
      this.isOpen = true;
    },
    close() {
      this.isOpen = false;
    },
    handleClickOutside(e) {
      if (!this.$el.contains(e.target)) {
        this.close();
      }
    },
  },
});

new Vue({
  el: '#app',
  methods: {
    onCardChanged(value) {
      this.items.forEach((n, i) => {
        this.$set(n, 'selected', n.versions.find(v => v.name === value.name) || null);
      });
    }
  },
  data: {
    items: [{
      id: 1,
      name: 'Play station',
      versions: [{ name: 'PS3' }, { name: 'PS4' }, { name: 'PS4 PRO' }]
    }, {
      id: 2,
      name: 'MBP',
      versions: [{ name: 'Air' }, { name: 'PRO 2015' }, { name: 'PRO 2016' }]
    }, {
      id: 3,
      name: 'Xbox',
      versions: [{ name: '360' }, { name: 'One' }, { name: 'One S' }]
    }],
  }
});