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' }]
}],
}
});