インクリメンタルサーチとは
インクリメンタルサーチ(英語: incremental search)は、アプリケーションにおける検索方法のひとつ。検索したい単語をすべて入力した上で検索するのではなく、入力のたびごとに即座に候補を表示させる
完成品
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>インクリメンタルサーチ</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<!-- v-model を指定する -->
<input type="text" placeholder="検索" v-model="search">
<!-- sort とソート順選択欄を v-modelで結ぶ -->
<select v-model="sort">
<option value="">ソート無し</option>
<option value="asc">昇順</option>
<option value="desc">降順</option>
</select>
<!-- v-for を使ったリストをアニメーションさせるためのコンポーネント <transition-group>key 属性を付ける必要がある -->
<transition-group tag="ul">
<!-- <li v-for="item in list"> listプロパティの値をv-forで回す -->
<!-- fileterdListを表示 -->
<li v-for="item in sortedList" v-bind:key="item.id">
{{ item.text }}
</li>
</transition-group>
</div>
<script src="main.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</body>
</html>
JS
new Vue({
el: "#app",
data:{
//入力フォームに入力された値を表すデータを定義
search: '',
//現在どの並び順でソートしているのかを表すデータ
sort: '',
//、次は検索対象のデータを定義
list: [
{ id: 1, text: 'Python' },
{ id:2, text: 'Ruby'},
{ id:3, text: 'PHP'},
{ id:4, text: 'JavaScript'},
{ id:5, text: 'Java'},
{ id:6, text: 'Go'},
{ id:7, text: 'C'},
{ id:8, text: 'C#'},
{ id: 9, text: 'Rails' },
{ id:10, text: 'Django'},
{ id:11, text: 'MySQL'},
{ id:12, text: 'Vue.jst'},
{ id:13, text: 'react'},
{ id:14, text: 'Docker'},
{ id:15, text: 'unity'},
{ id:16, text: 'jQuery'}
]
},
computed: {
//検索処理としてfileterdListを定義
filteredList: function(){
//filter のコールバック関数内では引数に配列の各項目が渡され、返り値が true となった項目のみ出力
return this.list.filter(function(item){
//ある文字列に他の文字列が含まれているかどうかを調べる時は indexOfを使用
//item.text 文字列に、this.search という文字列が含まれている時に、その文字列の場所を表す数値を返し、含まれていないときには -1 を返し
return item.text.indexOf(this.search) > -1
}, this)
},
//ソート後のデータを返す算出プロパティ sortedList
sortedList: function(){
var copy = this.filteredList.slice()
if(this.sort === 'asc' ){
//comparatorAsc メソッドをコールバックとして sort 関数に渡す
return copy.sort(this.comparatorAsc)
} else if(this.sort === 'desc') {
//降順に並べ替えるためのコールバック関数は comparatorDesc
return copy.sort(this.comparatorDesc)
} else{
return copy
}
}
},
methods:{
comparatorAsc: function(itemA, itemB){
if(itemA.text < itemB.text){
return -1
} else if(itemA > itemB.text){
return 1
} else{
return 0
}
},
comparatorDesc: function(){
if(itemA.text > itemB.text){
return -1
} else if(itemA < itemB.text){
return 1
} else{
return 0
}
},
}
});
CSS
body{
font-family: sans-serif;
}
input,
select{
padding: 2px 8px;
font-size: inherit;
vertical-align: middle;
}
ul {
position: relative;
margin-top: 6px;
padding: 0;
width: 300px;
list-style: none;
}
li{
margin: 0;
padding: 10px;
border-bottom: 1px solid #ddd;
}
.v-move{
transition: transform 300ms ease-out;
}
.v-enter-active {
transition: 300ms;
}
.v-enter{
opacity: 0;
}
.v-enter-to{
opacity: 1;
}
.v-leave-active{
transition: 300ms;
}
.v-leave{
opacity: 1;
}
.v-leave-to{
opacity: 0;
}