Vue cli インストールした Vue 2.2 を使用しています。
文字だとわかり難いのでイメージはこんな感じです。

SelectList.vue
SelectListという名称でメインの機能を作成します。
components/SelectList.vue
<template>
<div>
<div>
<ul class="item-list is-border">
<li v-for="item in selectItems">
{{ item.name }}
<a class="delete-btn" @click="onDeleteItem(item)">X</a>
</li>
</ul>
<button class="btn" @click="isModal = true">アイテム選択</button>
</div>
<transition name="modal" v-if="isModal">
<div class="overlay" @click="isModal = false">
<div class="panel" @click.stop>
<h3>アイテムを選択してください</h3>
<div class="scroll-box">
<ul class="item-list">
<li v-for="item in filteredItems" @click="onSlectItem(item)">
{{ item.name }}
</li>
</ul>
</div>
<button class="btn" @click="isModal = false">閉じる</button>
</div>
</div>
</transition>
</div>
</template>
<script>
export default {
props: ['setSelectItems'],
mounted() {
for (var i=1; i<=100; i++) {
this.items.push({
id: i,
name: 'item' + i
});
}
},
data() {
return {
isModal: false, // Modak表示フラグ
items: [], // すべてのアイテム
selectItems: this.setSelectItems // 選択したアイテム
}
},
methods: {
// アイテムを選択
onSlectItem(item) {
this.selectItems.push({
'id': parseInt(item.id),
'name': item.name
});
this.isModal = false;
},
// アイテムを削除
onDeleteItem(item) {
let index = this.selectItems.indexOf(item);
this.selectItems.splice(index, 1);
}
},
computed: {
// 選択されているオプションは非表示
filteredItems() {
let data = this.items;
let selects = this.selectItems;
data = data.filter(function (row) {
for (var i=0; i<selects.length; i++) {
if (selects[i].id == row['id']) {
return false;
break;
}
}
return true;
});
return data;
}
}
}
</script>
<style lang="scss">
.overlay {
background: rgba(0, 0, 0, .8);
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 900;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.panel {
width: 600px;
height: 400px;
background: #fff;
padding: 20px;
h3 {
margin-bottom: 10px;
}
}
.scroll-box {
height: 300px;
overflow-y: auto;
margin-bottom: 20px;
border: solid 1px #bbb;
}
.item-list {
list-style: none;
padding: 0;
&.is-border {
border: solid 1px #bbb;
margin-bottom: 20px;
}
li {
border-top: solid 1px #bbb;
margin-top: -1px;
padding: 10px;
display: flex;
justify-content: space-between;
&:first-child {
border-top: none;
}
}
}
.btn {
width: 100%;
padding: 15px;
border: none;
background: #eee;
}
</style>
- 3行目
-
setSelectItemsは選択しているアイテムの配列です。propsでコンポーネントの呼び出し元からデータを受け取ります。 - 5~10行目
-
仮なので
forでitemのデータを生成してます。本来ならどこかから読み込む感じになるかと思います。 - 19〜33行目
-
methodsは追加と削除だけです。 - 36〜50行目
- 選択しているアイテム(selectItems)は表示させなくしています。
App.vue
先ほど作成したSelectList.vueをApp.vueで呼び出します。
<template>
<div id="app">
<select-list :setSelectItems="selectItems"></select-list>
</div>
</template>
import SelectList from "./components/SelectList.vue";
export default {
name: 'app',
data() {
return {
selectItems: [
{
id: 2,
name: 'item2'
},{
id: 4,
name: 'item4'
}
]
}
},
components: {
SelectList
},
}
選択したいアイテムの変数を作成してsetSelectItemsに渡すだけですね。



