使用 axios (Vue 3) 接收的本地 JSON 中的搜索列表

Posted

技术标签:

【中文标题】使用 axios (Vue 3) 接收的本地 JSON 中的搜索列表【英文标题】:Search list in local JSON received with axios (Vue 3) 【发布时间】:2021-08-22 23:57:21 【问题描述】:

我想使用搜索框过滤数据时遇到问题。我不得不使用此参考中的代码 Vue2 Search in List received via Axios 仍然无法正常工作。

我想从我的本地 json 文件(我放在公共文件夹中)获取数据。这是我的 db.json 文件:


  "products": [
    
      "id": 1,
      "nama": "Skin10004",
      "deskripsi": "Madagascar Centella Toning"
    ,
    
      "id": 2,
      "nama": "Some By Mi",
      "deskripsi": "AHA-BHA-PHA 30 Days"
    ,
    
      "id": 3,
      "nama": "Avoskin",
      "deskripsi": "Your Skin Bae Series Toner"
    
  ]

使用 axios,我成功获取了所有数据。但我的问题是,我的搜索框在用户输入时无法过滤数据。这是我在 Products.vue 中的代码:

// Here's my view code
<template>
  <div>
    <Navbar />
    <div class="container">

    <!-- Here's my search box but fail to filter the data-->
      <div class="row mt-3">
        <div class="col">
          <div class="input-group mb-3">
            <input
              v-model="search"
              type="search"
              class="form-control"
              placeholder="Cari disini .."
              aria-label="Cari"
              aria-describedby="basic-addon1"
              @keyup="searchProducts"
            />

            <div class="input-group-prepend">
              <span class="input-group-text" id="basic-addon1">
                <b-icon-search></b-icon-search>
              </span>
            </div>
          </div>
        </div>
      </div>

    <!-- Here's where my product display and success to display all data -->
      <div class="row mb-4">
        <div
          class="col-md-4 mt-4"
          v-for="product in products"
          :key="product.id"
        >
          <CardProduct :product="product" />
        </div>
      </div>

    </div>
  </div>
</template>

<script src="https://unpkg.com/vue@2.4.2"></script>
<script>
// Navbar and CardProduct is not the issue
import Navbar from "@/components/Navbar.vue";
import CardProduct from "@/components/CardProduct.vue";
import axios from "axios";

export default 
  name: "Products",
  components: 
    Navbar,
    CardProduct,
  ,

  data() 
    return 
      products: [], // Where I store the data to display in view
      search: null, // initialize search null
    ;
  ,

  // Where I grab all the data in db.json
  mounted() 
    axios
      .get("/db.json")
      .then((response) => this.setProducts(response.data.products))
      .catch((error) => console.log(error));
  ,

  // Where I store the data to display in view
  methods: 
    setProducts(data) 
      this.products = data;
    ,
  ,

  // Here's my problem. Search can't filter the display data
  computed: 
    searchProducts: function () 
      let searchTerm = (this.search || "").toLowerCase();
      return this.products.filter(function (product) 
        let nama = (product.nama || "").toLowerCase();
        let deskripsi = (product.deskripsi || "").toLowerCase();
        return (
          nama.indexOf(searchTerm) > -1 || deskripsi.indexOf(searchTerm) > -1
        );
      );
    ,
  ,
  
  created() 
    setTimeout(() => (this.products = products), 500);
  ,

;
</script>

在控制台中,我遇到了这样的错误:

    未捕获的 ReferenceError:未定义产品 [Vue 警告]:v-on 处理程序出错:“TypeError:handler.apply 不是函数” TypeError: handler.apply 不是函数

谢谢。

【问题讨论】:

部分问题(特别是数字 2 和 3)是您将 @keyup 绑定到计算属性。计算出的并不完全是一个函数,因此 handler.apply is not a function。您可能应该将 searchProducts 设为方法而不是计算方法。 【参考方案1】:

Uncaught ReferenceError: products is not defined

错误可能出现在created() 中,其中products 似乎没有在任何地方定义:

export default 
  created()                             
    setTimeout(() => (this.products = products), 500);
  ,                                  ^^^^^^^^

看起来你甚至不需要它,因为你的 mounted() 钩子填充了 this.products。只需完全删除 created() 钩子即可。

[Vue warn]: Error in v-on handler: "TypeError: handler.apply is not a function"

此错误是由您的 keyup 绑定到计算的 prop searchProducts 引起的,这不太合理。我怀疑您实际上希望显示的产品列表由用户的搜索词自动过滤。问题是显示的产品列表循环通过所有products,但它应该循环通过searchProducts

<div
  class="col-md-4 mt-4"
  v-for="product in searchProducts"
  :key="product.id"
>
  <CardProduct :product="product" />
</div>

只需删除@keyup 绑定,然后更新v-for 变量,如上所示。

【讨论】:

哇,非常感谢您的帮助。现在可以使用了

以上是关于使用 axios (Vue 3) 接收的本地 JSON 中的搜索列表的主要内容,如果未能解决你的问题,请参考以下文章

axios请求VUE-CLI3项目本地json文件404

vue.js 和 axios 使用但无法在 response.headers 中接收 set-cookie

使用 Vue.js + axios 将本地图像链接到 api 数组

VUE.JS 通过 webpack-simple 中的 axios 从 url 接收一个 json 文件

vue使用本地json

vue之axios请求数据本地json