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

Laravel Nova实现关联筛选:将Manufacturer筛选器值传递给Model筛选器

实现Laravel Nova中Manufacturer与Model筛选器的联动

我之前也碰到过这个需求,要实现Nova里筛选器的联动,得搞定两个核心点:后端能根据已选厂商动态返回对应型号,还有前端在厂商筛选变化时自动刷新型号筛选器的选项。下面分版本给你具体解决方案:

方案一:Laravel Nova 4+(推荐,原生支持依赖筛选)

Nova 4及以上版本自带筛选器依赖功能,直接用这个特性最省心:

1. 修改Model筛选器,添加依赖配置

在Model筛选器类里,加上$dependsOn属性,指定它依赖的Manufacturer筛选器(默认key是类名的蛇形命名manufacturer):

class Model extends Filter
{
    public $component = 'select-filter';
    // 指定依赖的筛选器key
    public $dependsOn = ['manufacturer'];

    // 保留原有的apply方法不变
    public function apply(Request $request, $query, $value)
    {
        return $query->whereHas('product', function ($query) use ($value) {
            $query->where('model', $value);
        });
    }

    public function options(Request $request)
    {
        // 初始化Product查询
        $query = Product::select('model')
            ->withoutGlobalScopes()
            ->withoutTrashed()
            ->groupBy('model')
            ->orderBy('model');

        // 从request中获取已选的厂商值
        $selectedManufacturer = $request->input('filters.manufacturer');
        
        // 如果有选中的厂商,添加筛选条件
        if ($selectedManufacturer) {
            $query->where('manufacturer', $selectedManufacturer);
        }

        return $query->pluck('model')
            ->mapWithKeys(function ($model) {
                return [$model => strtolower($model)];
            })
            ->toArray();
    }
}

2. 自定义筛选器名称的适配(可选)

如果你给Manufacturer筛选器自定义了名称(通过name()方法),得同步修改Model筛选器的依赖配置和取值逻辑:

比如Manufacturer筛选器自定义了name:

class Manufacturer extends Filter
{
    public function name()
    {
        return 'custom_manufacturer';
    }

    // 其他代码不变
}

那Model筛选器里要调整成这样:

public $dependsOn = ['custom_manufacturer'];

// 在options方法中获取值
$selectedManufacturer = $request->input('filters.custom_manufacturer');

配置完之后,用户选厂商的时候,Nova会自动触发Model筛选器的选项重新加载,后端会根据选中的厂商返回对应的型号列表。

方案二:Laravel Nova 3及以下版本(自定义前端组件)

如果用的是Nova 3或更早版本,没有内置依赖筛选支持,就得自己写Vue组件实现联动:

1. 创建自定义筛选器组件

在resources/js/components/filters/DependentSelectFilter.vue里写组件代码:

<template>
  <select-filter
    :field="field"
    :value="value"
    @input="handleInput"
  ></select-filter>
</template>

<script>
import SelectFilter from '@nova/filters/SelectFilter'

export default {
  components: { SelectFilter },
  props: ['field', 'value', 'resourceName', 'resourceId'],
  watch: {
    // 监听厂商筛选器的变化
    '$root.$filters.manufacturer': function(newVal) {
      // 重新加载当前筛选器的选项
      this.field.options = this.fetchOptions(newVal)
    }
  },
  methods: {
    handleInput(value) {
      this.$emit('input', value)
    },
    async fetchOptions(manufacturer) {
      const response = await Nova.request().get(`/nova-api/reviews/filters/${this.field.key}/options`, {
        params: {
          filters: { manufacturer }
        }
      })
      return response.data
    }
  },
  mounted() {
    // 初始化时加载默认选项
    this.fetchOptions(this.$root.$filters.manufacturer).then(options => {
      this.field.options = options
    })
  }
}
</script>

2. 注册自定义组件

在resources/js/app.js里注册这个组件:

Nova.booting((Vue, router) => {
  Vue.component('dependent-select-filter', require('./components/filters/DependentSelectFilter.vue').default)
})

3. 修改Model筛选器的组件类型

把Model筛选器的$component改成自定义组件:

class Model extends Filter
{
    public $component = 'dependent-select-filter';

    // apply和options方法和方案一中的保持一致
}

4. 编译前端资源

运行npm run dev或者npm run prod编译组件资源,生效后就能看到联动效果了。

注意事项

  • 确保Product模型的manufacturer和model字段数据干净,没有空值或无效数据,避免分组后出现异常选项。
  • 如果你用了软删除,withoutTrashed()能保证不会包含已删除的产品数据。
  • 测试时可以检查Network请求,确认厂商筛选值是否正确传递到后端,以及返回的型号列表是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:29:06