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
に渡すだけですね。