在Vue3中动态过滤for循环数据源
目标
我想根据搜索栏的输入筛选在for循环中使用的数据源。
示例
我有数据源[{TITLE:&Q;TITLE1&Q;},{TITLE:&Q;TITLE2&Q;}]。我在我的搜索栏中输入标题1。我只希望for循环的经过筛选的数据源显示标题为1的对象
问题
搜索输入更改(...)方法似乎起作用了,this.filteredPosts数据源似乎更改正确。但是,在HTML模板中,数据源似乎没有更新。它始终同时包含两个对象。
Home.vue
<template>
<Searchfield @searchInputChange="searchInputChange" />
<div v-for="post in filteredPosts" :key="post.id">
{{ post.title }}
</div>
</template>
<script>
import { ref } from 'vue'
import Searchfield from '../components/Searchfield.vue'
export default {
name: 'Home',
components: { Searchfield },
setup() {
let filteredPosts = ref([])
let allPosts = [
{
"id": 1,
"title": "Title1",
},
{
"id": 2,
"title": "Title2",
}
]
filteredPosts.value = [...allPosts]
return { allPosts, filteredPosts }
},
methods: {
searchInputChange(value) {
const filterPosts = this.allPosts.filter(post => post.title.toLowerCase().includes(value.toLowerCase()));
this.filteredPosts.value = [...filterPosts]
}
}
}
</script>
Searchfield.vue
<template>
<input type="text" @change="searchInputChange" placeholder="Search...">
</template>
<script>
export default {
name: 'Searchfield',
setup(props, context) {
const searchInputChange = (event) => {
context.emit('searchInputChange', event.target.value)
}
return { searchInputChange }
}
}
</script>
谢谢!
解决方案
在setup
中使用ref时,需要使用value
属性更改它的值(或读取值),以便setup
到filteredPosts
的所有赋值都应该类似于filteredPosts.value = ....
在setup
(比如说methods
)之外,filteredPosts
是反应对象(组件实例)的正常反应属性,不需要.value
(使用它是错误的)
所有这些都非常令人困惑,这也是不建议混合使用组合API和选项API的原因之一--只使用其中之一。
在您的情况下,filteredPosts
可以是一个简单的computed
,而无需在每次更改输入时手动重新分配它...
const app = Vue.createApp({
setup(){
const searchTerm = Vue.ref('')
let allPosts = [
{
"id": 1,
"title": "Title1",
},
{
"id": 2,
"title": "Title2",
}
]
const filteredPosts = Vue.computed(() => allPosts.filter(post => post.title.toLowerCase().includes(searchTerm.value.toLowerCase())) )
return {
searchTerm,
filteredPosts
}
},
})
app.component('Searchfield', {
props: ['modelValue'],
emits: ['update:modelValue'],
setup(props, { emit }) {
const model = Vue.computed({
get: () => props.modelValue,
set: (newValue) => emit('update:modelValue', newValue)
})
return { model }
},
template: `<input type="text" v-model="model" placeholder="Search...">`
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.2.23/dist/vue.global.js"></script>
<div id='app'>
<searchfield v-model="searchTerm"></searchfield>
<div v-for="post in filteredPosts" :key="post.id">
{{ post.title }}
</div>
</div>
相关文章