Před nějakým časem jsem vytvořil složku automatického dokončování v vue na projekt, ve kterém jsem zapojen.
Ale dnes jsem zjistil malou chybu.
Když jsem se vybrat možnost Chci s kliknutím myši, možnost nedostane přenášeny, jak můžete vidět ve console.log ()
které je v uvedeném příkladu. Kdybych klikněte znovu na jinou možnost, co se objeví console.log ()
, je možnost předem vybraná.
Pokud jsem dal setTimeout( () => {}, 200)
již detekuje a vydávat možnost, ale myslím, že to není nejlepší řešení pro tento případ.
Nějaký návrh?
příklad
const Autocomplete = {
name: autocomplete,
template: #autocomplete,
props: {
items: {
type: Array,
required: false,
default: () => Array(150).fill().map((_, i) => `Fruit ${i+1}`)
},
isAsync: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
isOpen: false,
results: [],
search: ,
isLoading: false,
arrowCounter: 0
};
},
methods: {
onChange() {
console.log( this.search)
// Let's warn the parent that a change was made
this.$emit(input, this.search);
},
setResult(result, i) {
this.arrowCounter = i;
this.search = result;
this.isOpen = false;
},
showAll() {
this.isOpen = !this.isOpen;
(this.isOpen) ? this.results = this.items : this.results = [];
},
},
computed: {
filterResults() {
// first uncapitalize all the things
this.results = this.items.filter(item => {
return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
});
return this.results;
},
},
watch: {
items: function(val, oldValue) {
// actually compare them
if (val.length !== oldValue.length) {
this.results = val;
this.isLoading = false;
}
}
},
mounted() {
document.addEventListener(click, this.handleClickOutside);
},
destroyed() {
document.removeEventListener(click, this.handleClickOutside);
}
};
new Vue({
el: #app,
name: app,
components: {
autocomplete: Autocomplete
}
});
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
.autocomplete {
position: relative;
width: 130px;
}
.autocomplete-results {
padding: 0;
margin: 0;
border: 1px solid #eeeeee;
height: 120px;
overflow: auto;
width: 100%;
}
.autocomplete-result {
list-style: none;
text-align: left;
padding: 4px 2px;
cursor: pointer;
}
.autocomplete-result.is-active,
.autocomplete-result:hover {
background-color: #4aae9b;
color: white;
}
<script src=https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js></script>
<div id=app>
<autocomplete />
</div>
<script type=text/x-template id=autocomplete>
<div class=autocomplete>
<input type=text @blur=onChange v-model=search @click=showAll />
<ul id=autocomplete-results v-show=isOpen ref=scrollContainer class=autocomplete-results>
<li class=loading v-if=isLoading>
Loading results...
</li>
<li ref=options v-else v-for=(result, i) in filterResults :key=i @click=setResult(result, i) class=autocomplete-result :class={ 'is-active': i === arrowCounter }>
{{ result }}
</li>
</ul>
</div>
</script>