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

Vue项目实现页面加载及搜索时获取展示列表数据的方法

问题排查

你现有代码跑不通首屏加载的核心原因有3个:

  • 首屏调用fetchArtists拉到的全量艺术家数据存在了artists字段,但模板里v-for遍历的是result数组,这个数组初始为空,自然首屏啥都不显示
  • 写了filteredResult计算属性但完全没在模板里用到,全量数据逻辑和搜索数据逻辑完全割裂
  • 模板里错用了React的className语法,Vue里绑定静态类名直接写class就行

实现方案

根据数据量大小选一种实现即可,两类场景都能覆盖:

方案1:前端本地过滤(适合总数据量1000条以内的场景,请求少响应快)

首屏只拉一次全量数据存在本地,用户输入搜索词时直接在前端过滤,不用重复发请求,改动最小:

  • 删掉多余的result字段,全量数据统一存在artists数组
  • 模板里直接遍历filteredResult计算属性
  • 删掉keyup绑定的搜索请求方法,靠v-model绑定的searchQuery自动触发计算属性更新
  • 修正模板里的类名写法错误

修正后完整代码:

<template>
  <div class="body">
    <div class="searchBar">
      <i class="bi bi-search"></i>
      <input
        placeholder="Search for artists"
        type="text"
        v-model="searchQuery"
      />
    </div>
    <div class="artists">
      <!-- 注意把className改成class,遍历计算属性 -->
      <div
        class="artist__list"
        v-for="artistResult in filteredResult"
        :key="artistResult.id"
      >
        <h4>{{ artistResult.name }}</h4>
      </div>
      <!-- 可选:加无结果提示 -->
      <div v-if="filteredResult.length === 0">暂无匹配艺术家</div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
import "./body.css";
export default {
  data() {
    return {
      artists: [], // 存储全量艺术家数据
      searchQuery: "",
    };
  },
  mounted() {
    // 首屏拉取全量数据
    this.fetchArtists();
  },
  computed: {
    filteredResult() {
      const keyword = this.searchQuery.trim().toLowerCase();
      // 搜索词为空直接返回全量
      if (!keyword) return this.artists;
      // 搜索词不为空走前端过滤
      return this.artists.filter((item) =>
        item.name.toLowerCase().includes(keyword)
      );
    },
  },
  methods: {
    async fetchArtists() {
      try {
        const res = await axios.get("http://localhost:3000/artists");
        this.artists = res.data;
      } catch (error) {
        console.error("拉取艺术家列表失败:", error);
      }
    },
  },
};
</script>

方案2:接口搜索(适合总数据量很大的场景,靠后端返回匹配结果)

如果数据量太大前端存不下,就保留搜索接口请求,注意处理搜索词清空的场景,避免发多余请求:

  • 统一用result数组作为渲染数据源,首屏拉全量、搜索拉匹配结果都赋值给这个字段
  • 给搜索输入加防抖,避免每按一个键就发一次请求(比如用户连续输3个字只发1次请求)
  • 搜索词清空时,不用发请求,直接把之前存的全量artists赋值给result即可

核心改动代码片段:

// 可以引入lodash的防抖方法,不想引依赖也可以自己实现简单防抖
import _ from "lodash";

export default {
  data() {
    return {
      artists: [], // 存首屏拉到的全量数据,清空搜索时复用
      result: [], // 页面渲染用的列表
      searchQuery: "",
    };
  },
  mounted() {
    this.fetchArtists();
  },
  watch: {
    // 监听搜索词变化,防抖300ms触发搜索
    searchQuery: {
      handler: _.debounce(function (newVal) {
        const keyword = newVal.trim();
        // 关键词为空直接展示全量,不发请求
        if (!keyword) {
          this.result = this.artists;
          return;
        }
        // 有关键词再调用搜索接口
        this.searchArtist(keyword);
      }, 300),
    },
  },
  methods: {
    async fetchArtists() {
      try {
        const res = await axios.get("http://localhost:3000/artists");
        this.artists = res.data;
        this.result = res.data; // 首屏拉到数据直接赋值给渲染列表
      } catch (error) {
        console.error("拉取艺术家列表失败:", error);
      }
    },
    async searchArtist(keyword) {
      try {
        const res = await axios.get(`http://localhost:3000/artists?q=${keyword}`);
        this.result = res.data;
      } catch (error) {
        console.error("搜索失败:", error);
      }
    },
  },
}

模板部分记得把v-for的遍历值改回result,把className改成class即可。

小提示:如果用方案2,建议给axios加请求取消逻辑,避免后发的请求比先发的早返回导致结果错乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:15:24