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

Vue中对象数组搜索过滤功能实现及代码问题求助

问题描述

我是Vue和JavaScript新手,已经实现了通过提交按钮把三个输入框的内容存入data里定义的sellBill数组。现在需要实现搜索功能,点击搜索后把sellBill中匹配的结果输出到控制台,但目前搜索按钮和过滤部分的代码有不少问题。

我试过把搜索内容存入searchBox数组,然后在found函数里和sellBill的数据比对,但没成功。


原HTML代码
<div id="app">

    <input v-model="customers" type="text" placeholder="customers">
    <input v-model="productName" type="text" placeholder="productName">
    <input v-model="price" type="number" placeholder="price">

    <button @click="addMessage()">submit</button>

    <input v-for="searchBox" type="text" placeholder="search...">
    <button @click="found()">search</button>

    <hr>

    <table>
        <tr>
            <th>customers</th>
            <th>productName</th>
            <th> price</th>
            <th>activities</th>
        </tr>

        <tr v-for="(item, index) in sellBill">
            <td>
                <input type="text" v-if="item.edit === true" v-model="item.customers">
                <p v-else>{{item.customers}}</p>
            </td>
            <td>
                <input type="text" v-if="item.edit === true" v-model="item.productName">
                <p v-else>{{item.productName}}</p>
            </td>
            <td>
                <input type="number" v-if="item.edit === true" v-model="item.price">
                <p v-else>{{item.price}}</p>
            </td>
            <td>
                <button @click="remove(index)">delete</button>

                <button v-if="item.edit === false" @click="item.edit = true">edit</button>
                <button v-else @click="item.edit = false">submit</button>
            </td>
        </tr>
    </table>

    <div>
        {{total()}}
    </div>
</div>

原Script代码
const {createApp} = Vue

    createApp({
        data() {
            return {
                customers: "",
                productName: "",
                searchBox: [],
                sellBill: []
            }
        },

        methods: {
            addMessage() {
                let x = (this.price)
                if (typeof x === 'number') {
                    this.sellBill.push({
                        customers: this.customers,
                        productName: this.productName,
                        price: this.price,
                        edit: false
                    })
                    this.customers = ''
                    this.productName = ''
                    this.price = ''
                } else {
                    this.price = ""
                    alert("The field is empty or The price must be number")
                }
            },
            remove(index) {
                this.sellBill.splice(index, 1)
            },
            total() {
                let sum = 0
                for (let i = 0; i < this.sellBill.length; i++) {
                    sum += (this.sellBill[i].price)
                }
                return sum
            },
            found() {
                this.searchBox.push({
                    searchItem: this.customers,
                })
                this.customers = '';
                const find = this.sellBill.filter(el => el.customers === this.searchItem || el.productName === this.searchItem)
                console.log(find)
            }
        }
    }).mount("#app")

问题分析与修正方案

核心问题点

  1. 搜索输入框错误使用v-for="searchBox",导致渲染多个输入框,实际只需单个搜索框
  2. found函数中未定义searchItem变量,却用它做匹配,且复用customers变量会和添加数据的输入框冲突
  3. 价格判断逻辑有漏洞:number类型输入框空值时是字符串,typeof x === 'number'无法正确判断

修正后的完整代码

HTML部分

<div id="app">
    <input v-model="customers" type="text" placeholder="客户">
    <input v-model="productName" type="text" placeholder="产品名称">
    <input v-model="price" type="number" placeholder="价格">

    <button @click="addMessage()">提交</button>

    <!-- 去掉错误的v-for,绑定单独的搜索关键词变量 -->
    <input v-model="searchKeyword" type="text" placeholder="搜索...">
    <button @click="found()">搜索</button>

    <hr>

    <table>
        <tr>
            <th>客户</th>
            <th>产品名称</th>
            <th>价格</th>
            <th>操作</th>
        </tr>

        <tr v-for="(item, index) in sellBill" :key="index">
            <td>
                <input type="text" v-if="item.edit" v-model="item.customers">
                <p v-else>{{item.customers}}</p>
            </td>
            <td>
                <input type="text" v-if="item.edit" v-model="item.productName">
                <p v-else>{{item.productName}}</p>
            </td>
            <td>
                <input type="number" v-if="item.edit" v-model="item.price">
                <p v-else>{{item.price}}</p>
            </td>
            <td>
                <button @click="remove(index)">删除</button>
                <button v-if="!item.edit" @click="item.edit = true">编辑</button>
                <button v-else @click="item.edit = false">提交</button>
            </td>
        </tr>
    </table>

    <div>总价:{{total()}}</div>
</div>

Script部分

const { createApp } = Vue

createApp({
    data() {
        return {
            customers: "",
            productName: "",
            price: "",
            searchKeyword: "", // 新增:单独存储搜索关键词
            searchBox: [], // 若不需要搜索历史可删除
            sellBill: []
        }
    },

    methods: {
        addMessage() {
            const priceNum = Number(this.price);
            // 修正价格判断:确保是有效数字且大于0
            if (!isNaN(priceNum) && priceNum > 0) {
                this.sellBill.push({
                    customers: this.customers,
                    productName: this.productName,
                    price: priceNum,
                    edit: false
                })
                // 清空输入框
                this.customers = ''
                this.productName = ''
                this.price = ''
            } else {
                this.price = ""
                alert("价格不能为空且必须是有效数字")
            }
        },
        remove(index) {
            this.sellBill.splice(index, 1)
        },
        total() {
            // 用reduce简化求和逻辑
            return this.sellBill.reduce((sum, item) => sum + item.price, 0)
        },
        found() {
            const keyword = this.searchKeyword.trim();
            if (!keyword) {
                console.log("请输入搜索内容");
                return;
            }
            // 模糊匹配客户名或产品名,要精确匹配改回===即可
            const matchedItems = this.sellBill.filter(item => 
                item.customers.includes(keyword) || item.productName.includes(keyword)
            );
            console.log("匹配结果:", matchedItems);
            // 若需存储搜索历史,可取消下方注释
            // this.searchBox.push(keyword);
            this.searchKeyword = '';
        }
    }
}).mount("#app")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:54:55