vue.js - 使用搜索功能设置 v-autocomplete
问题描述
尝试在没有观察者的情况下设置 v-autocomplete,流程将是:
- 输入字符串,函数接受值
- 函数在 api 中搜索字符串并返回一个列表
- 列表被放入“条目”
- 计算属性“tagsFound”被重新评估。
- 显示“tagsFound”(因为它们是)这里
:items
的文档和我的代码之间的主要区别是我尝试在没有观察者的情况下执行此操作,而不是使用简单的函数。相关代码:
<v-autocomplete
v-model="newTag"
:items="tagsFound"
:loading="loading"
:search-input.sync="search"
color="white"
hide-no-data
hide-selected
:placeholder="$t('search_terms.new_tag')"
></v-autocomplete>
...
data() {
return {
newTag: '',
entries: [],
....
methods: {
...
async search(term){
this.query.term = term
this.entries = await this.searchTerms(this.query)
},
...
computed: {
tagsFound(){
return this.entries
}
}
预期行为是搜索键入的术语并将结果显示为下拉列表。 实际行为是它不搜索,因此不显示任何内容。
解决方案
sync
修饰符有效地使道具表现得像,v-model
所以就像v-model
有道具和事件一样。该值需要是一个属性,而不是一个方法,所以如果是一个方法是:search-input.sync="search"
没有意义的。search
您示例中的tagsFound
计算属性实际上并没有做任何事情。如果您只是要返回entries
,不妨entries
直接在模板中使用。
不知道为什么要在没有 a 的情况下执行此watch
操作,但可以通过拆分search-input.sync
为 prop/event 对或使用带有 getter 和 setter 的计算属性来完成。下面的示例使用后一种方法。
function fakeServer (search) {
return new Promise(resolve => {
setTimeout(() => {
resolve([
'Red', 'Yellow', 'Green', 'Brown', 'Blue', 'Pink', 'Black'
].filter(c => c.toLowerCase().includes(search.toLowerCase())))
}, 1000)
})
}
new Vue({
el: '#app',
data () {
return {
newTag: '',
entries: [],
queryTerm: ''
}
},
computed: {
search: {
get () {
return this.queryTerm
},
set (searchInput) {
if (this.queryTerm !== searchInput) {
this.queryTerm = searchInput
this.loadEntries()
}
}
}
},
created () {
this.loadEntries()
},
methods: {
async loadEntries () {
this.entries = await fakeServer(this.queryTerm || '')
}
}
})
<link href="https://unpkg.com/vuetify@1.5.16/dist/vuetify.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@1.5.16/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-autocomplete
v-model="newTag"
:items="entries"
:search-input.sync="search"
></v-autocomplete>
</v-app>
</div>