You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt.js(Vue.js框架)中Vuetify v-tabs动态过滤门店数据问题

动态实现Vuetify v-tabs门店字母过滤方案

嘿,我来帮你搞定这个动态过滤的问题!你之前手动切片的方式确实不够灵活,一旦门店数据更新或者新增字母标签,就得手动调整切片范围,太麻烦了。我们可以用计算属性+动态渲染的方式彻底解决这个问题,代码也会简洁很多。

第一步:简化数据获取逻辑

首先删掉那些手动切片的storeA/storeB变量,只保留排序后的完整门店列表,这样后续的过滤逻辑都基于这个完整数组:

<script>
import axios from "axios";
export default {
  asyncData({ req, params }) {
    return axios.get(process.env.apiURL + "stores").then(res => {
      // 按门店名称本地化排序,保持之前的逻辑
      const sortedStores = res.data.sort((a, b) => a.store_name.localeCompare(b.store_name));
      return { stores: sortedStores };
    });
  },
  data() {
    return {
      apiURL: process.env.apiURL,
      active: 0, // 默认选中第一个标签(#)
      tabs: ['#', 'A', 'B', 'C', 'D', 'E'] // 统一管理所有标签项
    }
  },
  // 接下来添加计算属性
  computed: {
    filteredStores() {
      const currentTab = this.tabs[this.active];
      if (currentTab === '#') {
        // 可选逻辑:如果#标签需要显示非字母开头的门店,替换成下面的过滤代码
        // return this.stores.filter(store => {
        //   const firstChar = store.store_name.charAt(0).toUpperCase();
        //   return !(firstChar >= 'A' && firstChar <= 'Z');
        // });
        
        // 当前逻辑:#标签显示所有门店
        return this.stores;
      } else {
        // 过滤出以当前字母开头的门店,忽略大小写确保匹配准确
        return this.stores.filter(store => {
          const firstChar = store.store_name.charAt(0).toUpperCase();
          return firstChar === currentTab;
        });
      }
    }
  }
};
</script>

第二步:重构模板,动态渲染标签和内容

原来重复写多个<v-tab-item>的方式太冗余了,我们只需要一个v-tab-item,配合计算属性filteredStores动态渲染内容,标签也用循环生成:

<template>
  <v-container grid-list-md text-xs-center>
    <br/>
    <v-tabs v-model="active" light grow slider-color="red">
      <!-- 循环生成所有标签 -->
      <v-tab v-for="(tab, index) in tabs" :key="index">
        {{ tab }}
      </v-tab>

      <!-- 单个tab-item显示过滤后的门店 -->
      <v-tab-item>
        <v-layout row wrap>
          <!-- 注意:用store_name作为key比index更可靠,避免数据更新时的渲染问题 -->
          <v-flex v-for="(store, index) in filteredStores" :key="store.store_name" xs6 sm4 md2 lg2 xl3>
            <v-card light>
              <nuxt-link :to="'/store/'+store.store_name">
                <v-card-media :src="`${apiURL}containers${store.store_image}`" height="80px"></v-card-media>
                <v-card-text class="blue">{{ store.store_name }}</v-card-text>
              </nuxt-link>
            </v-card>
          </v-flex>
        </v-layout>
      </v-tab-item>
    </v-tabs>
  </v-container>
</template>

方案优势

  • 完全动态:新增字母标签只需要在tabs数组里添加元素,不需要修改任何过滤逻辑
  • 自动响应:计算属性filteredStores会随着active选中状态的变化自动更新过滤结果
  • 代码简洁:消除了大量重复的模板代码,维护成本大幅降低
  • 鲁棒性强:忽略大小写的匹配逻辑,避免因为门店名称大小写不一致导致的匹配失败

可选调整

如果你的#标签需要专门显示非字母开头的门店,只需要替换计算属性里currentTab === '#'对应的逻辑(我已经在代码里注释了可选方案)。

内容的提问来源于stack exchange,提问作者user6579211

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:22:11