Vuex,firestore:显示过滤结果
Posted
技术标签:
【中文标题】Vuex,firestore:显示过滤结果【英文标题】:Vuex, firestore: Show the filtered result 【发布时间】:2021-02-05 06:53:27 【问题描述】:我想将过滤功能添加到我的项目中。 现在我有了一个按钮组件来触发过滤器搜索。
如果我按下餐厅按钮,结果将是风暴中具有“餐厅”值的商店。
另一方面,如果我按下超市按钮,结果将是firestore中具有“超市”价值的商店。
现在我正在使用 vuex,我正在使用 Result.vue 中的 mapGetters 从“getMenuItems”中检索数据。
我在 Buttons.vue 中添加的方法是触发突变。 如果我按下餐厅按钮,餐厅数据将被推送到 menu.js 中的“restaurantItems”中。
我想要实现的是,如果我按下餐厅按钮,Result.vue 将读取“restaurantItems”而不是“getMenuItems”。
我尝试在 Result.vue 的计算属性中使用 if 语句,但找不到解决方案。
如果我的方法是错误的,我很高兴你告诉我正确的方法。
Buttons.vue
<template>
<div>
<section class="button-section">
<div class="d-flex buttons">
<b-button class="supermarket" @click.prevent="showSupermarket">Supermarket</b-button>
<b-button class="restaurant" @click.prevent="showRestaurant">Restaurant</b-button>
</div>
</section>
</div>
</template>
<script>
import fireApp from '@/plugins/firebase'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();
import mapGetters from 'vuex'
import store from '../store'
export default
name: 'Buttons',
data()
return
supermarket: "",
restaurant: ""
,
methods:
showSupermarket()
const supermarketRef = db.collection('Product').where('type', '==', "Supermarket")
supermarketRef.get()
.then(snapshot =>
if (snapshot.empty)
console.log('No matching documents.');
return;
snapshot.forEach(doc =>
const supermarket = doc.data()
console.log(supermarket)
this.supermarket = supermarket
//triger mutation here.
this.$store.commit('showSupermarketResult', this.supermarket)
//console.log(doc.id, '=>', doc.data());
);
)
.catch(err =>
console.log('Error getting documents', err);
);
,
showRestaurant()
const restaurantRef = db.collection('Product').where('type', '==', "Restaurant")
restaurantRef.get()
.then(snapshot =>
if (snapshot.empty)
console.log('No matching documents.');
return;
snapshot.forEach(doc =>
const resutaurant = doc.data()
console.log(resutaurant)
this.resutaurant = resutaurant
this.$store.commit('showRestaurantResult', this.resutaurant)
//console.log(doc.id, '=>', doc.data());
);
)
.catch(err =>
console.log('Error getting documents', err);
);
,
</script>
Result.vue
<template>
<div>
<Navbar />
<Map />
<Buttons />
<div class="main">
<section class="cards">
<div class="card" v-for="(item, index) in getMenuItems" :key="index">
<div class="card-icons" v-if="item.quantity > 0">
<div class="card-icon">
<div class="card__image-container" v-for="(sample, index) in item.sample" :key="index">
<!-- <router-link to="/product"> -->
<router-link :to="name:'Product',params:id:item.id">
<img
:src="sample"
/>
</router-link>
<div class="card__content">
<div class="card__info">
<span class="text--medium"> item.business </span>
<span class="card__distance text--medium"> item.quantity left</span>
</div>
</div>
</div>
</div>
<div class="icons">
<div class="time">
<span>until<br> item.limitObject </span>
</div>
<div class="fav">
<span>Heart</span>
</div>
<div class="price">
<span> item.initial <br> item.sale </span>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
</template>
<script>
import axios from 'axios';
import Navbar from "@/components/Navbar.vue";
import Buttons from "@/components/Buttons.vue";
import Map from "@/components/Map.vue";
import fireApp from '@/plugins/firebase'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();
import mapGetters from 'vuex'
export default
name: "UserLocation",
data()
return
address: "",
error: "",
spinner: false
,
components:
Navbar,
Map,
Buttons
,
created()
//vuexfire
const dbMenuRef = db.collection('Product')
this.$store.dispatch('setMenuRef', dbMenuRef)
,
computed:
...mapGetters([
'getMenuItems'
])
,
methods:
</script>
menu.js
import firestoreAction from 'vuexfire'
import fireApp from '@/plugins/firebase'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();
const dbMenuRef = db.collection('Product')
const state =
menuItems:[],
supermarketItems:[],
restaurantItems: [],
store:[]
const getters =
getMenuItems: state => state.menuItems,
supermarketItems: state => state.supermarketItems,
restaurantItems: state => state.restaurantItems
const mutations =
showSupermarketResult(state, supermarket)
state.menuItems.push(supermarket);
,
showRestaurantResult(state, restaurant)
state.restaurantItems.push(restaurant);
,
const actions =
setMenuRef: firestoreAction(context =>
return context.bindFirestoreRef('menuItems', dbMenuRef)
),
export default
state,
mutations,
getters,
actions
【问题讨论】:
【参考方案1】:我会重构问题中的大部分代码,因为其中许多是重复的,例如:
Buttons.vue:重构按钮操作
<b-button class="supermarket" @click.prevent="showCollection('supermarket')">Supermarket</b-button>
<b-button class="restaurant" @click.prevent="showCollection('restaurant')">Restaurant</b-button>
Buttons.vue:重构方法
methods:
showCollection(type)
this.$store.dispatch('setCollectionType', type)
menu.js:将 firestore 逻辑移动到操作中,有副作用
const state =
...,
currentType: 'menu'
const mutations =
...,
setCurrentType(state, type)
state.currentType = type
const actions =
...
setCollectionType: ( commit, state , type)
commit('setCurrentType', type)
const mutations =
supermarket: 'showSupermarketResult',
restaurant: 'showRestaurantResult'
const states =
supermarket: 'supermarketItems',
restaurant: 'restaurantItems'
if (state[states[type]].length) return
const collectionRef = db.collection('Product').where('type', '==', type)
collectionRef.get()
.then(snapshot =>
if (snapshot.empty)
console.log('No matching documents.');
return;
snapshot.forEach(doc =>
const data = doc.data()
commit(mutations[type], data)
);
)
.catch(err =>
console.log('Error getting documents', err);
);
,
Result.vue:最后,重构如何显示结果
<div class="card" v-if="currentType === 'supermarket'" v-for="(item, index) in supermarketItems" :key="index">
<!-- Iterate supermarket items-->
</div>
<div class="card" v-if="currentType === 'restaurant'" v-for="(item, index) in restaurantItems" :key="index">
<!-- Iterate restaurant items-->
</div>
【讨论】:
并且每次按下按钮时,都会将项目添加到数组中。我想我需要解决这个问题。 @YoheiUmezu 你可以随时取消menu.js
上不必要的数据更新,看我更新的答案以上是关于Vuex,firestore:显示过滤结果的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI + Firestore - 基于从 Firestore 返回的数组的过滤器列表
如何从 Vuex 商店中删除 Firestore 快照侦听器
在 vuex 操作中访问 this.$fireStore (Nuxt.js)