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

Nuxt对接Laravel分页接口实现客户端实时搜索过滤失效问题

问题根源

你当前的实现逻辑是后端通过paginate()仅返回单页数据,前端仅持有当前页的数据集,所以本地过滤只能作用于当前页内容,这是前后端分工逻辑未对齐导致的,并非代码语法错误。

解决方案

共有两种可选实现方式,可根据你的业务数据量选择:

方案1:服务端实现搜索逻辑(推荐,适配任意数据量)

这是性能最优、适用范围最广的方案,无需前端拉取全量数据,改动成本低:

  • 前端监听搜索字段search.domain的变化,每次变化后将搜索参数带入接口请求,同时将页码重置为1
  • 后端Laravel接口接收搜索参数后,先执行模糊匹配筛选,再调用paginate()返回筛选后的分页结果

代码改动示例

前端JS新增搜索监听、调整请求参数:

export default {
  // 原有代码不变
  watch: {
    page (val) {
      this.navigateToPage(this.page)
    },
    // 新增搜索词监听
    'search.domain'() {
      this.page = 1
      this.getDomains()
    }
  },
  methods: {
    getDomains () {
      this.hasErrors = false
      // 拼接请求参数
      const params = new URLSearchParams({
        page: this.page,
        domain: this.search.domain
      })
      this.$axios.get(`${process.env.API_URL}/api/domains?${params.toString()}`, { timeout: 60000 }).then(res => {
        // 原有处理逻辑不变
      })
    }
  }
}

Laravel后端接口改造:

public function index(Request $request)
{
    $query = Domain::query();
    // 存在搜索参数时先执行模糊筛选
    if ($request->filled('domain')) {
        $query->where('domain', 'like', "%{$request->input('domain')}%");
    }
    // 筛选完成后再分页
    $domains = $query->paginate(10);
    return response()->json([
        'success' => true,
        'domains' => $domains
    ]);
}

方案2:前端全量拉取后做本地分页+搜索(仅适合总数据量<1000条的场景)

如果不想改造后端,且业务数据量很小,可以一次性拉取全量数据到前端,再自行实现分页和搜索:

  • 后端新增全量数据接口,或把原有接口的paginate()改为get()返回所有记录
  • 前端存储全量数据,先做搜索过滤,再对过滤后的结果手动分页

代码改动示例

前端JS调整逻辑:

export default {
  data () {
    return {
      // 原有变量不变
      allDomains: [], // 存储全量域名数据
      perPage: 10 // 自定义每页条数,和原分页规则保持一致
    }
  },
  created () {
    this.getAllDomains() // 初始化拉取全量数据
  },
  methods: {
    getAllDomains () {
      this.hasErrors = false
      this.$axios.get(`${process.env.API_URL}/api/domains/all`, { timeout: 60000 }).then(res => {
        if (res.data.success) {
          this.isLoading = false
          // 处理registrar字段格式
          this.allDomains = res.data.domains.map(domain => {
            if (typeof domain.registrar == 'string' && domain.registrar != null) {
              domain.registrar = JSON.parse(domain.registrar)
            }
            return domain
          })
        }
      }).catch(err => {
        this.isLoading = false
        this.hasErrors = true
      })
    },
    // 原有getDomains、navigateToPage方法可删除
  },
  computed: {
    // 第一步:对全量数据做搜索过滤
    filteredDomains () {
      return this.allDomains.filter(domain => {
        return domain.domain.toLowerCase().includes(this.search.domain.toLowerCase())
      })
    },
    // 第二步:对过滤后的结果做分页切割
    paginatedDomains () {
      const start = (this.page - 1) * this.perPage
      return this.filteredDomains.slice(start, start + this.perPage)
    },
    // 分页组件总条数替换为过滤后的总条数
    filteredTotal () {
      return this.filteredDomains.length
    }
  },
  watch: {
    // 搜索词变化时重置页码
    'search.domain'() {
      this.page = 1
    }
  }
}

模板部分调整:

  • v-for遍历的对象从filteredDomains改为paginatedDomains
  • 分页组件的total-rows属性从domains.total改为filteredTotal
  • 分页组件的per-page属性改为perPage

你提到的循环拉取所有分页构造全量列表的方式完全没有必要,会增加不必要的请求开销,稳定性也差,优先选择以上两种方案即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 01:06:03