typeahead.js っぽいものをVue.jsで自作してみた
3711 ワード
結局使わなかったのだが、typeahead.js みたいにデータがサジェストされるフォームを作ってみた。
Prefecture.vue
<template>
<div>
<typeahead :options="prefectures"></typeahead>
</div>
</template>
<script>
export default {
components: {
typeahead: require('./Typeahead.vue')
},
data () {
return {
prefectures: ['hokkaido', 'aomori', 'iwate', 'miyagi', 'akita', 'yamagata', 'fukushima', 'ibaraki', 'tochigi', 'gunma', 'saitama', 'chiba', 'tokyo', 'kanagawa', 'niigata', 'toyama', 'ishikawa', 'fukui', 'yamanashi', 'nagano', 'gifu', 'shizuoka', 'aichi', 'mie', 'shiga', 'kyoto', 'osaka', 'hyogo', 'nara', 'wakayama', 'tottori', 'shimane', 'okayama', 'hiroshima', 'yamaguchi', 'tokushima', 'kagawa', 'ehime', 'kochi', 'fukuoka', 'saga', 'nagasaki', 'kumamoto', 'oita', 'miyazaki', 'kagoshima', 'okinawa']
}
}
}
</script>
Typeahead.vue
<template>
<div>
<input type="text" v-model="selected" @keyup="onKeyUp" @input="onKeyUp"
@focus="filterOptions" @blur="lostFocus">
<ul class="suggestion-area" v-if="isListVisible">
<li v-for="(option, i) in filteredOptions" @click="selectOption" :class="liClass(i)" >
{{ option }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
selected: '',
selectedIndex: 0,
filteredOptions: [],
isListVisible: false,
}
},
props: ['options'],
methods: {
liClass(i) {
return {
active: (i === this.selectedIndex),
}
},
onKeyUp (e) {
console.log(e)
switch (e.key) {
case 'Control':
case 'CapsLock':
case 'Shift':
return false
case 'ArrowDown':
if (this.selectedIndex !== this.filteredOptions.length - 1) {
this.selectedIndex += 1
}
break;
case 'ArrowUp':
if (this.selectedIndex > 0) {
this.selectedIndex -= 1
}
break;
case 'Enter':
this.selected = this.filteredOptions[this.selectedIndex]
this.isListVisible = false
break;
default:
this.filterOptions(e)
}
},
filterOptions (e) {
if (this.selected === '') {
this.isListVisible = false
return false
}
this.isListVisible = true
this.filteredOptions = this.options.filter( (text) => {
var regex = new RegExp(this.selected, 'i')
return (text.match(regex))
})
this.selectedIndex = 0
},
selectOption (e) {
this.selected = e.target.innerText
this.isListVisible = false
},
lostFocus (e) {
setTimeout(() => {this.isListVisible = false}, 500)
},
}
}
</script>
<style lang="scss">
.suggestion-area {
z-index: 0;
position: absolute;
background: white;
max-height: 100px;
li {
border: solid 1px gray;
padding: 2px;
list-style: none;
}
.active {
background-color: orange;
}
}
</style>
意外と簡単だった。さすがVue.js。
Author And Source
この問題について(typeahead.js っぽいものをVue.jsで自作してみた), 我々は、より多くの情報をここで見つけました https://qiita.com/acro5piano/items/13456f2c3d5ee64844c2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .