前回書いたこの記事よりスクレイピングしたデータを使用して、Vue.jsで表示してフィルター機能を実装していきたいと思います。
Pythonを利用してVueで表示したい方はこれらの記事を参照してみて下さい。
イメージはこんな感じです。ランキング部分をVue.jsで表示しています。
表示しているデータはPythonでエクセルから読み込んでjsonに変換しているだけです。
絞り込み機能のフォーム部分でそれぞれにあったフィルターや検索機能を実装します。
スタイルはBootStrapで簡単に整えているだけです。
検索機能実装
都道府県の検索機能を実装します。
<body>
<th>都道府県</th>
<td><input class="col-sm-2 col-form-label" v-model="keyword" placeholder="Search..." ></td>
〜省略〜
<table class="table table-hover">
<thead>
<tr>
<th>[[ column.ranking ]]</th>
<th>[[ column.prefectures ]]</th>
<th>[[ column.money ]]</th>
<th>[[ column.book_price ]]</th>
</tr>
</thead>
<tbody>
<tr v-for="data in datas">
<td>[[ data.ranking ]]</td>
<td>[[ data.prefectures ]]</td>
<td>[[ data.money ]]</td>
<td>[[ data.book_price ]]</td>
</tr>
</tbody>
</table>
〜省略〜
<script>
const vm = new Vue({
el: '#app',
delimiters: ['[[', ']]'], // Flaskのdelimiterとの重複を回避
data:{
series: [],
datas: [],
column: {},
keyword: '',
},
created: function() {
this.loadData('/get/book', [])
},
watch: {
keyword() {
this.filter()
},
},
methods: {
loadData(url, data) {
axios.get(url, data)
.then(res => {
vm.series = res.data.books
vm.datas = res.data.books
vm.column = res.data.column
})
.catch(err => {
console.log(err);
});
},
filter() {
this.filterPrefectures(this.series)
},
filterPrefectures(series) {
const books = series;
this.datas = books.filter(book => book.prefectures.includes(this.keyword))
},
}
})
</script>
</body>
〜省略〜
簡単に説明すると、watch:{ }でkeyword変数を監視してv-model=”keyword”に変化があると
filter()メソッドが実行されます。
filter()メソッドにはさらにfilterPrefectures(this.series)を呼び出します。
全て(1位〜47位)のデータが入っているseriesを引数として渡しています。
filterPrefectures()メソッド内の処理はkeywordに一致する文字列をthis.datasに格納し直して表示します。
全てを持っているデータ(vm.series = res.data.books)と、
表示する用のデータvm.datas = res.data.booksを持って保持しておくことがポイントです。
「島」と入力してみました。
島を含む都道府県が表示されました。
ランキングの絞り込み
次はランキングの絞り込みをします。
フォームの追加とメソッドの追加をします。
<body>
〜省略〜
<th>順位</th>
<td>
<div class="text-box-area">
<div class="text-box">
<input class="col-sm-2 col-form-label" v-model.number="lower" placeholder="min...">
<span>〜</span>
<input class="col-sm-2 col-form-label" v-model.number="top" placeholder="max...">
</div>
</div>
</td>
〜省略〜
<script>
〜省略〜
data:{
series: [],
datas: [],
column: {},
keyword: '',
lower: '',
top: '',
},
watch: {
lower() {
this.filter()
},
top() {
this.filter()
},
},
methods: {
filter() {
this.filterPrefectures(this.series)
this.filterComparison (this.datas, this.lower, this.top, 'index_ranking')
},
〜省略〜
filterComparison(datas, low, top, key) {
const books = datas;
this.datas = books.filter(book => {
if(low === '' && top === '') return this.datas;
if(low !== '' && top === '') return (low <= book[key]);
if(low === '' && top !== '') return (top >= book[key]);
if(low !== '' && top !== '') return (low <= book[key] && book[key] <= top);
})
},
},
</script>
</body>
色々省略して分かりにくいですが、理解のため、あえてです。
都道府県検索と同様に、watch:{ }で監視してメソッドを実行しています。
ここでのポイントはfilterComparison( )で引数で渡しているデータです。
datasの中身はすでに都道府県検索でヒットしたデータとなっています。
filterをかける度にデータが削れていくイメージになります。
引数lowとtopは入力された値で、その数値の間のdataを返しています。
‘index_ranking’はjsonで定義したkeyです。
デベロッパーツールの「検証」で確認してみます。
このjsonデータは私がPythonで生成しています。
この記事↓と同じ要領でやってるので改めて本記事では記述しません。
とりあえずここでは、book[key]で呼び出して処理していることを理解してもらえればOKです。
都道府県に「島」を含む文字の絞り込みとランキングが31位以上の絞り込み結果です。
同じ要領で、年収(money)、書籍購入金額(book_price)をfilterかけていけば完成です。
下記イメージとなります。
都道府県「島」、順位「31」、年収「4,100,000」の絞り込み
都道府県「島」、順位「31」、年収「4,100,000」、書籍「3,500」の絞り込み
完成へ向けて頑張ってみて下さい。笑
自分で考えて完成させることがスキル向上への近道だと私は思っています。
完成のための情報はこれまでに私が書いたVue関係の記事のどこかにあるはずです。が、
抜けていたらすみません。。m(_ _)m
コメント