Vue3动态过滤for循环数据源
Dynamically filter for-loop data source in Vue3
目标
我想根据搜索栏的输入过滤 for 循环中使用的数据源。
例子
我有数据源 [{ title: "Title1" }, { title: "Title2" }]。我在搜索栏中输入“Title1”。我只希望 for 循环的过滤数据源显示带有“Title1”的对象
问题
searchInputChange(...) 方法似乎有效并且 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
是反应对象(组件实例)和 [=20= 的正常反应 属性 ] 不需要(使用它是错误的)
所有这些都非常令人困惑,这也是为什么不建议混合组合 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>
目标
我想根据搜索栏的输入过滤 for 循环中使用的数据源。
例子
我有数据源 [{ title: "Title1" }, { title: "Title2" }]。我在搜索栏中输入“Title1”。我只希望 for 循环的过滤数据源显示带有“Title1”的对象
问题
searchInputChange(...) 方法似乎有效并且 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
是反应对象(组件实例)和 [=20= 的正常反应 属性 ] 不需要(使用它是错误的)
所有这些都非常令人困惑,这也是为什么不建议混合组合 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>