复选框v-model只返回数组中的第一个关键字的问题



我在数组中有几个曲目,并有一个搜索和复选框来过滤曲目。但是,复选框只返回每个筛选器中第一个标识的字符串。因此,如果我点击pop的复选框——在下面的例子中——它将只显示只包含流行音乐类型的曲目。包含摇滚、流行类型的曲目将不会出现。这是Vue中的复合API。

脚本如下:

const searchTerm = ref('')
const genreFilter = ref([])
const moodsFilter = ref([])
const tempoFilter = ref([])
const themeFilter = ref([])
const filteredTracks = computed(() => {
let filtered = useSong.tracks;
if (searchTerm.value) {
const term = searchTerm.value.toLowerCase();
filtered = filtered.filter(track =>
track.description.toLowerCase().includes(term) || 
track.genre.toLowerCase().includes(term) ||
track.keywords.toLowerCase().includes(term) ||
track.moods.toLowerCase().includes(term)
);
}
if (genreFilter.value.length > 0) {
filtered = filtered.filter(track => genreFilter.value.includes(track.genre))
}
if (moodsFilter.value.length > 0) {
filtered = filtered.filter(track => moodsFilter.value.includes(track.moods))
}
if (tempoFilter.value.length > 0) {
filtered = filtered.filter(track => tempoFilter.value.includes(track.tempo))
}
if (themeFilter.value.length > 0) {
filtered = filtered.filter(track => themeFilter.value.includes(track.theme))
}
return filtered;
});

这里是html:

<div class="genres w-1/4"><h1 class="font-bold text-[#aeaeae]">Genres</h1><br>
<input class="css-checkbox" type="checkbox" id="Rock" key="genre" value="Rock" v- 
model="genreFilter">
<label class="css-label pl-2 text-s font-light text-[#aeaeae]" for="Rock">Rock</label> 
<input class="css-checkbox" type="checkbox" id="Pop" key="genre" value="Pop" v- 
model="genreFilter">
<label class="css-label pl-2 text-s font-light text-[#aeaeae]" for="Pop">Pop</label> 

我如何修改这一点,以便我可以选中多个类型框并让它们全部显示,仅删除未选中的框。任何帮助都将不胜感激。此外,你会注意到在过滤器中我有一个情绪,节奏和主题。每当我单击这些复选框时,数组中什么也没有出现,尽管数组具有匹配的情绪、节奏和主题。谢谢。

您的genreFilter变量是一个数组:

const genreFilter = ref([])

但是你把所有的东西都放在复选框里,v-model:

<input type="checkbox" value="Rock" v-model="genreFilter">

有效地将数组替换为字符串。

所以当你做

filtered = filtered.filter(track => genreFilter.value.includes(track.genre))

您呼叫的不是Array.prototype.includes(),而是String.prototype.includes()。这工作,但不是你想要的。

简单的解决方案是在复选框中使用索引:

<input type="checkbox" value="Rock" v-model="genreFilter[0]">

一个可能更好的解决方案是在勾选复选框时添加或删除元素:

<input type="checkbox" value="Rock" @change="updateGeneres($event.target)">

const updateGenres = ({value, checked}) => checked 
? (genreFilter.value.includes(value) || genreFilter.value.push(value))
: (genreFilter.value = genreFilter.value.filter(g => g !== value))

const { createApp, ref, computed} = Vue;
const App = {
setup(){
const genres = ['Rock', 'Pop']
const genreFilter = ref([])
const updateGenres = ({value, checked}) => checked
? (genreFilter.value.includes(value) || genreFilter.value.push(value))
: (genreFilter.value = genreFilter.value.filter(g => g !== value))
const items = [
{genre: 'Pop', title: 'This is Pop'},
{genre: 'Rock', title: 'This is Rock'},
{genre: 'Something Else', title: 'This is something else'},
]
const filteredItems = computed(() => genreFilter.value.length === 0 ? items : items.filter(i => genreFilter.value.includes(i.genre) ))
return {genres, genreFilter, updateGenres, filteredItems}
},
}
const app = createApp(App)
app.mount('#app')
<div id="app">

<div v-for="genre in genres">
<label>
<input
type="checkbox" 
:value="genre" 
@change="updateGenres($event.target)"
> {{ genre }}
</label>
</div>

Selected Genres: {{genreFilter}}

<ul>
<li v-for="item in filteredItems">{{ item.title }}</li>
</ul>

</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

下面是带有设置脚本 的SFC中的代码片段

相关内容