我如何根据函数触发来呈现 Vuex 状态?

How can i render a Vuex state depending on a function triggering?

我看到有几个这样的问题,但我无法从中得到任何进展,所以我会自己做一个。

事情如下。 我有一个状态“allCountries”,它是一个数组,最初充满了 250 个国家/地区对象。我在我的主页组件中正确呈现这些国家,问题是我想在单击按钮时过滤按钮所代表的大陆国家。例如,如果按钮显示“欧洲”,我想接收 属性“大陆”为欧洲的所有国家/地区。

我正在使用以下代码实现此目的:

const store = createStore({
state: {
    allCountries: [],
    filteredCountries: [],
    countryId: {},
},

mutations: {

    filterByContinent(state, payload) {
        let countries = [...state.allCountries];
        state.filteredCountries = countries.filter(
            (country) => country.continent === payload
        );
    },
},

问题是我不知道如何在单击按钮时呈现过滤的国家/地区,在 vuex 开发工具中我可以看到单击时“filteredCountries”状态如何填充正确的大洲国家/地区。

我正在尝试这个但没有用:

<template>
<div>
    <!-- <p class="homeTitle">COUNTRIES:</p> -->
    <ul class="countriesBox" v-if="allCountries">
        <li
            v-for="country in allCountries"
            :key="country.id"
            class="countryCard"
        >
            <br />
            <router-link
                :to="{
                    name: 'CountryDetail',
                    params: { id: country.Id },
                }"
                class="countryName"
                >{{ country.name }}</router-link
            >
            <br />
            <p class="countryContinent">{{ country.continent }}</p>
            <br />
            <img
                :src="`${country.flagImage}`"
                alt="country flag"
                class="flagImage"
            />
        </li>
    </ul>

    <ul class="countriesBox" v-else-if="filteredCountries">
        <li
            v-for="country in filteredCountries"
            :key="country.id"
            class="countryCard"
        >
            <br />
            <router-link
                :to="{
                    name: 'CountryDetail',
                    params: { id: country.Id },
                }"
                class="countryName"
                >{{ country.name }}</router-link
            >
            <br />
            <p class="countryContinent">{{ country.continent }}</p>
            <br />
            <img
                :src="`${country.flagImage}`"
                alt="country flag"
                class="flagImage"
            />
        </li>
    </ul>

    <div class="backAndForwardButtons">
        <button>&#10094;</button>
        <button>&#10095;</button>
    </div>

    <FiltersBar />
</div>
</template>

我正在正确映射状态

import { mapState } from "vuex";
import store from "../store";

export default {
    name: "HomePage",
    computed: {
        ...mapState(["allCountries"]),
        ...mapState(["filteredCountries"]),
    },
};

如果有人能提供帮助,我将不胜感激。

您的商店 getter 针对过滤后的国家可能是这样的

filteredCountries: (state) => cont => {
      return state.countries.filter(country=>{
       return country.continent===cont
    })
}

好吧,也许代码不那么准确,但我认为这个想法保持不变

如您所见,filteredCountries getter 有额外的参数,那是您选择的大陆所在的地方

然后在你的组件中

data(){
   return {
       cont_filter:"europe"
   }
}

希望将值更改为 cont_filter 不是问题,因为这就是您希望在单击按钮时更改的内容。现在你可以像这样简单地使用它

    <li v-for="country in filteredCountries(cont_filter)"
                :key="country.name">
        {{country.name}}
   </li>

您可以创建一个 getter 检查是否有 .lengthfilteredCountries。如果没有,则默认为allCountries,如:

countries(state) {
  return state.filteredCountries.length ? state.filteredCountries : state.allCountries
}

然后在您的组件中,您不必复制逻辑来呈现来自两个不同数据源的两个单独列表。只需要使用一个数据源,在本例中我称之为 countries