Vue Storefront:自定义属性过滤器显示标签而非选项ID
Static mappings like config.products.colorMappings work perfectly for fixed attributes like colors, but they’re not scalable for brands—since admins can add new brands anytime, hardcoding mappings means constant frontend rebuilds. Here’s how to make this dynamic by pulling brand names directly from your backend:
1. Update Your API to Fetch Brand Option Names
First, ensure your backend API returns both the option ID and human-readable label for the brand attribute.
For example, if you’re using Magento 2 as your backend, adjust your GraphQL query in the category-next module to include labels for brand options:
query GetCategoryAggregations($categoryId: String!) { products(filter: { category_id: { eq: $categoryId } }) { aggregations { attribute_code options { label value } } } }
If you’re using a different backend, modify your attribute fetch request to include the label alongside each option ID.
2. Store Brand Mappings in Vuex
Save the brand ID-to-name mapping in your Vuex catalog store so it’s accessible across filter components.
Add this action to store/catalog/actions.js:
async fetchBrandMappings({ commit }) { const attributeData = await this.$api.catalog.getProductAttributes(); const brandAttribute = attributeData.find(attr => attr.code === 'brand'); if (brandAttribute) { const brandMappings = brandAttribute.options.reduce((map, option) => { map[option.value] = option.label; // Map ID to its corresponding label return map; }, {}); commit('SET_BRAND_MAPPINGS', brandMappings); } }
Then add the mutation in store/catalog/mutations.js:
SET_BRAND_MAPPINGS(state, mappings) { state.brandMappings = mappings; }
Don’t forget to initialize brandMappings: {} in store/catalog/state.js.
3. Update the Filter Component to Use Dynamic Labels
Modify your brand filter component to pull labels from the Vuex state instead of static config.
In your brand filter component (e.g., components/Filter/BrandFilter.vue):
<template> <div class="filter-brand"> <h4 class="filter-title">Brand</h4> <div class="filter-options"> <label v-for="option in filter.options" :key="option.id" class="filter-option"> <input type="checkbox" :value="option.id" v-model="selectedOptions" /> <!-- Fallback to ID if mapping doesn't exist (for new brands not yet fetched) --> {{ $store.state.catalog.brandMappings[option.id] || option.id }} </label> </div> </div> </template>
4. Pre-Fetch Mappings on Category Page Load
Ensure the mappings load before the filter renders by calling the action in your category page component.
In pages/Category.vue:
async asyncData({ store }) { await store.dispatch('catalog/fetchBrandMappings'); // ... other category data fetching logic }
Bonus: Cache Mappings for Performance
To avoid re-fetching mappings on every category page load, add caching (e.g., using localStorage or Vuex persisted state). This keeps mappings stored until the admin updates brand options, reducing unnecessary API calls.
内容的提问来源于stack exchange,提问作者Sagar Guhe

