Vueを使ったWEBアプリで絞り込み検索を作りました。
GitHubはこちら
💎 概要
- 条件を選択する検索バーcomponentと場所データを管理するstore.jsでやりとりをし、表示する場所データリストを変更する。
- 検索バーcomponentでは、条件をstoreに伝えるだけでデータリストの操作に関与しない。
画面
環境
- vue(2.6.14)
- vuex(3.6.2)
- vuetify(2.6.0)
💎 コード
検索バーのcomponent
FilteringBarComp.vue
<template>
<v-form
ref="form"
class="form-container d-flex flex-column flex-md-row justify-md-space-between"
>
<div class="d-flex">
<v-select
class="select-area mx-2"
v-model="selectedArea"
:items="area"
item-text="label"
item_value="value"
label="AREA"
hint="エリアを選んでください"
persistent-hint
></v-select>
<v-select
class="select-category mx-2"
v-model="selectedCategory"
:items="category"
item-text="label"
item_value="value"
label="CATEGORY"
hint="施設の種類を選んでください"
persistent-hint
></v-select>
<v-select
class="select-member mx-2"
v-model="selectedMember"
:items="members"
label="MEMBER"
hint="メンバーを選んでください"
persistent-hint
></v-select>
</div>
<div class="d-flex align-center">
<v-btn
outlined
color="white"
@click="filterPlaceList()"
>絞り込む</v-btn>
<v-btn
class="ml-2"
outlined
color="white"
@click="resetPlacesList()"
>リセット</v-btn>
<div
class="result-text mx-3"
>検索結果:{{ $store.state.displayingPlaceList.length }}件
</div>
</div>
</v-form>
</template>
<script>
export default {
data: () => ({
// 絞り込み検索の項目リスト(メンバー)
members: [
"S.Coups",
"Jeonghan",
"Joshua",
"Jun",
"Hoshi",
"Wonwoo",
"Woozi",
"The8",
"Mingyu",
"Dokyeom",
"Seungkwan",
"Vernon",
"Dino"
],
// 絞り込み検索の項目リスト(場所)
area: [
{ label: "東京エリア", value: "tokyo" },
{ label: "大阪エリア", value: "osaka" },
{ label: "名古屋エリア", value: "nagoya" }
],
// 絞り込み検索の項目リスト(施設分類)
category: [
{ label: "道端", value: "roadside" },
{ label: "飲食店", value: "restaurant" },
{ label: "美術館", value: "museum" },
{ label: "公園", value: "park" },
{ label: "山", value: "mountain" },
{ label: "その他店", value: "others" },
],
filteredList: [],
selectedArea: null,
selectedCategory: null,
selectedMember: null,
}),
computed: {
placeList() { return this.$store.state.placeList },
},
methods: {
// storeのexcuteFilter関数を呼び出す関数
// 選択された条件は複数存在するのでオブジェクトで渡す
filterPlaceList() {
this.$store.dispatch('executeFilter', {
area: this.selectedArea,
category: this.selectedCategory,
member: this.selectedMember
})
},
// 絞り込み検索の条件をリセットする関数
resetPlacesList() {
this.$refs.form.reset();
this.$store.commit('resetFilter');
}
}
}
</script>
store.js
store.js(関係部分のみ)
export default new Vuex.Store({
state: {
// 全ての場所データリストJSON
placeList: placeList,
// 表示する場所データリスト(default: placeList)
displayingPlaceList: placeList,
},
getters: {
// 絞り込みfilter(エリア)
filterOfArea: (state) => (area) => {
if (area == "tokyo") {
return state.placeList.filter(place => place.id > 1000 && place.id < 1999);
} else if (area == "osaka") {
return state.placeList.filter(place => place.id > 2000 && place.id < 2999);
} else if (area == "nagoya") {
return state.placeList.filter(place => place.id > 3000 && place.id < 3999);
}
},
// 絞り込みfilter(カテゴリー)
filterOfCategory: (state) => (category) => {
return state.placeList.filter(item => item.placeCategory == category);
},
// 絞り込みfilter(メンバー)
filterOfMember: (state) => (member) => {
return state.placeList.filter(item => item.members.includes(member));
}
},
mutations: {
// 絞り込み後の場所データリストを反映させる関数
// 引数listで絞り込み後のデータリストを受け取り、displayingPlaceListに代入
setFilteredList(state, list) {
state.displayingPlaceList = list;
},
// 絞り込み検索のリセット関数
resetFilter(state) {
state.displayingPlaceList = state.placeList;
}
},
actions: {
// 絞り込み検索を行う本体関数
// 選択された条件がある場合、filterに通す
executeFilter({ commit }, { area, category, member }) {
let resultArr = this.state.placeList;
// もし条件が選択されている場合(引数でもらったオブジェクトに値がある場合)、filterを実行する
if (area != null) {
const resultAreaArr = this.getters.filterOfArea(area);
resultArr = resultArr.filter(item => resultAreaArr.includes(item));
}
if (category != null) {
const resultCategoryArr = this.getters.filterOfCategory(category);
resultArr = resultArr.filter(item => resultCategoryArr.includes(item));
}
if (member != null) {
const resultMemberArr = this.getters.filterOfMember(member);
resultArr = resultArr.filter(item => resultMemberArr.includes(item));
}
commit('setFilteredList', resultArr);
},
}
})
💎 思ったこと
- storeにこんなに関数を入れていいのか?