基于VueJS/JavaScript(ES5)的酒店房间描述搜索过滤问题排查
It looks like your current filter code is missing two critical pieces: it’s trying to access HotelRoomDescription directly on the hotel object (which doesn’t exist—those live in the rooms array), and it isn’t filtering the rooms themselves to only show matches. Let’s fix that step by step.
The Problem with Your Current Code
Your code checks hotel.HotelRoomDescription, but that property is nested inside each room in the hotel.rooms array. Even if you found a matching hotel, you’d still display all its rooms instead of just the ones that match the search term.
Corrected Filter Function
Here’s the revised code that properly iterates through rooms, filters hotels with matching rooms, and keeps only the relevant rooms for each matching hotel:
filterRooms() { const searchTerm = this.roomSearch.trim().toLowerCase(); // Return all hotels if no search term is entered if (!searchTerm) return this.hotels; // Process each hotel to check for matching rooms return this.hotels.map(hotel => { // Filter the hotel's rooms to only those matching the search term const matchingRooms = hotel.rooms.filter(room => room.HotelRoomDescription.toLowerCase().includes(searchTerm) ); // If there are matching rooms, return the hotel with filtered rooms if (matchingRooms.length > 0) { return { ...hotel, // Copy all original hotel properties rooms: matchingRooms // Replace rooms with only matches }; } // Exclude hotels with no matching rooms return null; }).filter(hotel => hotel !== null); // Remove null entries from results }
Key Improvements:
- Case Insensitivity: Converts both the search term and room description to lowercase for consistent, case-agnostic matches.
- Room-Level Filtering: For each hotel, we narrow down the
roomsarray to only entries whereHotelRoomDescriptionincludes the search term. - Smart Hotel Inclusion: Only hotels with at least one matching room are kept in the results, and they’re returned with their filtered room list.
- Immutability: Uses the spread operator (
...hotel) to create a copy of the hotel object instead of modifying the original data—this avoids unexpected reactivity issues in Vue.
How to Use It
Bind this filter function to your template where you’re rendering the hotel tree. For example:
<div v-for="hotel in filterRooms()" :key="hotel.HotelId"> <h3>{{ hotel.HotelName }}</h3> <div v-for="room in hotel.rooms" :key="room.RoomId"> <p>{{ room.HotelRoomDescription }}</p> </div> </div>
Now, when the user types in the roomSearch input, only hotels with matching rooms will appear, and only the matching rooms within those hotels will be displayed. When the search box is empty, all hotels and rooms show up as expected.
内容的提问来源于stack exchange,提问作者Moni

