首页 > 解决方案 > 使用 axios (Vue 3) 接收的本地 JSON 中的搜索列表

问题描述

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

我想从我的本地 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>

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

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

谢谢。

标签: javascriptjsonvue.jsaxiosvuejs3

解决方案


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变量,如上所示。


推荐阅读