VueJS中如何基于文本框输入值实现组件的筛选显示与隐藏?
Hey there! Let's break down what's going wrong with your current code and get it working the way you want.
What's Off With Your Current Logic
Looking at your v-if conditions:
- For ComponentA:
search.includes('ComponentA') || search.length == 0 - For ComponentB:
search.includes('ComponentB') || search.length == 0
This setup should actually:
- Show both components when the input is empty (since
search.length == 0is true for both) - Hide both components when you type something that doesn't match either component name (like "test")
But you're seeing the opposite: nothing shows when empty, both show when typing anything. That makes me think either there's a typo in your actual code (like using && instead of ||) or you might have mixed up your intended behavior.
Based on your goal to "only filter out specific components", I'm guessing you want one of these outcomes:
- Empty input = show all components; typing a component name = show only that component
- Empty input = show nothing; typing a component name = show only that matching component
Let's fix this for both scenarios.
Solution 1: Show All When Empty, Filter on Exact Match
If you want all components visible when the input is empty, and only the matching one when you type the full component name:
<template> <input type="text" v-model="search"> <ul> <li><ComponentA v-if="!search || search === 'ComponentA'" /></li> <li><ComponentB v-if="!search || search === 'ComponentB'" /></li> </ul> </template> <script setup> import ComponentA from '../components/ComponentA.vue' import ComponentB from '../components/ComponentB.vue' import { ref } from 'vue' const search = ref('') </script>
Solution 2: Fuzzy Match (Show Component on Partial Input)
If you want to show ComponentA when you type any part of its name (like "A" or "Comp"), and same for ComponentB:
<template> <input type="text" v-model="search"> <ul> <li><ComponentA v-if="!search || search.trim().toLowerCase().includes('a')" /></li> <li><ComponentB v-if="!search || search.trim().toLowerCase().includes('b')" /></li> </ul> </template> <script setup> import ComponentA from '../components/ComponentA.vue' import ComponentB from '../components/ComponentB.vue' import { ref } from 'vue' const search = ref('') </script>
Solution 3: Hide All When Empty, Show Only Matching Component
If you want nothing visible when the input is empty, and only the matching component when you type its name:
<template> <input type="text" v-model="search"> <ul> <li><ComponentA v-if="search.includes('ComponentA')" /></li> <li><ComponentB v-if="search.includes('ComponentB')" /></li> </ul> </template> <script setup> import ComponentA from '../components/ComponentA.vue' import ComponentB from '../components/ComponentB.vue' import { ref } from 'vue' const search = ref('') </script>
Pro Tip for Scaling
If you end up with more than a couple components, avoid repeating v-if logic by using a computed property and dynamic components. This keeps your code cleaner:
<template> <input type="text" v-model="search"> <ul> <li v-for="component in filteredComponents" :key="component.name"> <component :is="component.instance" /> </li> </ul> </template> <script setup> import ComponentA from '../components/ComponentA.vue' import ComponentB from '../components/ComponentB.vue' import { ref, computed } from 'vue' const search = ref('') const componentList = [ { name: 'ComponentA', instance: ComponentA }, { name: 'ComponentB', instance: ComponentB } ] const filteredComponents = computed(() => { const query = search.value.trim() // Toggle this line to switch between empty input showing all vs nothing if (!query) return componentList // Replace with return [] to hide all when empty return componentList.filter(item => item.name.includes(query)) }) </script>
内容的提问来源于stack exchange,提问作者Localhousee

