我正在尝试创建一个通用搜索组件,并带有一个事件,该事件随搜索字符串一起返回给父级,以便父级实际上可以过滤结果。
使用下面的代码,为什么computed.filteredDocuments
的值更改时this.searchCriteria
不重新计算,我该如何调整代码以便在调用updatedSearchString
时重新计算?
父项
<template>
<search :searchCriteria="searchCriteria" @searchString="updatedSearchString" />
<div v-for="(doc, index) in filteredDocuments" v-bind:key="index">
<div>{{doc.filename}}</div>
</div>
</template>
<script>
import store from '../store/index'
import { mapState } from 'vuex'
// import _ from 'lodash'
import Search from '../components/search'
export default {
name: 'Parent',
components: {
Search: Search
},
data () {
return {
searchCriteria: ''
}
},
computed: {
...mapState({
documents: state => state.documents.items
}),
filteredDocuments () {
console.log('in computed')
return _(this.documents)
.filter(this.applySearchFilter)
.value()
}
},
methods: {
updatedSearchString (searchString) {
this.searchCriteria = searchString <-- I WOULD HAVE EXPECTED BY UPDATING THIS IT WOULD TRIGGER COMPUTED.FILTEREDDOCUMENTS TO RECOMPUTE
}
},
applySearchFilter (doc) {
console.log('in applySearchFilter')
// If no search criteria return everything
if (this.searchCriteria === null) {
return true
}
if (doc.filename.toLowerCase().includes(this.searchCriteria.toLowerCase())) {
return true
}
return false
}
}
</script>
子组件
<template>
<div>
<q-search v-model="search" placeholder="Search" />
</div>
</template>
<script>
export default {
name: 'Search',
props: {
searchCriteria: { type: String, required: true }
},
data () {
return {
search: null
}
},
mounted () {
this.search = this.searchCriteria // Clone
},
watch: {
search: function (newVal, oldVal) {
// If no search criteria return everything
if (!newVal) {
this.clearSearch()
}
this.$emit('searchString', newVal) <-- THIS EMITS THE SEARCH VALUE TO THE PARENT
}
}
}
</script>
答案 0 :(得分:0)
我遇到的将您的示例代码转换成一段代码的问题是骆驼大小写/烤肉串大小写问题:HTML不区分大小写,因此该事件应该是kebab-case,而不是camelCase。本示例按预期进行过滤。
M+1
new Vue({
el: '#app',
data: {
searchCriteria: '',
documents: [{
filename: 'FirstFile'
},
{
filename: 'SecondFile'
},
{
filename: 'LastOne'
}
]
},
methods: {
updatedSearchString(searchString) {
this.searchCriteria = searchString
},
applySearchFilter(doc) {
console.log('in applySearchFilter')
// If no search criteria return everything
if (this.searchCriteria === null) {
return true
}
if (doc.filename.toLowerCase().includes(this.searchCriteria.toLowerCase())) {
return true
}
return false
}
},
computed: {
filteredDocuments() {
console.log('in computed')
return this.documents
.filter(this.applySearchFilter)
}
},
components: {
search: {
template: '#child-template',
props: {
searchCriteria: {
type: String,
required: true
}
},
computed: {
search: {
get() {
return this.searchCriteria;
},
set(value) {
this.$emit('search-string', value);
}
}
}
}
}
});