🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Q&A

解決済

3回答

1395閲覧

Vue 一覧のソート。computedの動きについて

gichorin

総合スコア14

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

0グッド

1クリップ

投稿2019/12/24 06:50

編集2019/12/24 06:53

Vueを勉強しています。

https://jp.vuejs.org/v2/examples/grid-component.html
公式にあるテーブルソートのサンプルを参考に、
入力フィールドの一覧を作成し、ソートするサンプルを作りました。

■事象
ヘッダークリック後、sortBy ⇒ filteredHeroesと動いてデータの表示順が変ります。
その状態で、Sortした列のデータを変更すると、再度filteredHeroesが実行され、並び順が変ってしまいます。
Sortをしていない列のデータを変更しても、filteredHeroesは動きません。

■質問1
上記事象についてcomputedを使用しているので、sort.sortKey、itemsに変更があったとき動くと考えています。
しかしSortを行っていない列のデータの場合、データを変更してもfilteredHeroesは動きません。なぜでしょうか。

■質問2
Sortした列のデータを変更しても、filteredHeroesを動かさないようにしたい場合はソースをどのように修正したら良いでしょうか。
現在の想定では、computedをやめて、methodsに移すしかないと考えています。

作成中のためうまくSortがされないことがありますが、filteredHeroesが動く事象は確認できます。
index.html

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 6</head> 7<body> 8 9<div id="demo"> 10 <table> 11 <thead> 12 <tr> 13 <th class="id" @click="sortBy('id')">ID</th> 14 <th class="comment" @click="sortBy('comment')">コメント</th> 15 </tr> 16 </thead> 17 <tbody> 18 <tr v-for="(item, idx) in filteredHeroes"> 19 <th><input type="text" value="1" v-model="item.id" ></th> 20 <td><input type="text" value="1" v-model="item.comment" ></td> 21 </tr> 22 </tbody> 23 </table> 24</div> 25<script> 26new Vue({ 27 el: '#demo', 28 data: { 29 items: [ 30 { "id": 1, "comment": "1行目" }, 31 { "id": 2, "comment": "2行目" } 32 ], 33 sort: { 34 sortKey: '', 35 sortOrders: {} 36 } 37 }, 38 computed: { 39 filteredHeroes: function () { 40 console.log('filteredHeroesが実行されます。'); 41 var sortKey = this.sort.sortKey; 42 var order = this.sort.sortOrders[sortKey] || 1; 43 var items = this.items; 44 if (sortKey) { 45 items = items.slice().sort(function (a, b) { 46 a = a[sortKey]; 47 b = b[sortKey]; 48 return (a === b ? 0 : a > b ? 1 : -1) * order; 49 }) 50 } 51 return items; 52 } 53 }, 54 mounted() { 55 this.sort.sortOrders["id"] = 1; 56 this.sort.sortOrders["comment"] = 1; 57 }, 58 methods: { 59 sortBy: function (key) { 60 console.log('sortByが実行されます。:' + key); 61 this.sort.sortKey = key; 62 this.sort.sortOrders[key] = this.sort.sortOrders[key] * -1; 63 } 64 } 65}); 66</script> 67</body> 68</html> 69コード

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

まずは自分で算出プロパティの仕組みを理解すること。

投稿2019/12/27 04:07

gichorin

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

https://qiita.com/tmak_tsukamoto/items/7623f458448fa7cd01c7
上記ページを参考に回答します。

オブジェクトや配列は中の要素を直接変更しても変更検知されません。
オブジェクトを作り直した上でthis.$set()を使って更新してみてください。

投稿2019/12/25 09:01

redara

総合スコア344

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gichorin

2019/12/27 04:06

ご回答ありがとうございます。 算出プロパティの仕組を調べているため、返答に時間がかかりました。 ためしにオブジェクトのプロパティ値や、配列の値を変更してみましたが、computeが反応します。 今回の事象と少し違うかもしれません。 ありがとうございます。
guest

0

■質問1
参考URL:算出プロパティとウォッチャ

上記の参考URLによりますと
算出プロパティはリアクティブな依存関係にもとづきキャッシュされるようです。

今回のケースですと、ソートに関係ない情報を更新した場合
算出プロパティが自分の結果を返す時に無縁のデータのため
filteredHeroesの中身が再実行されず、
キャッシュされるデータを返そうとしているのだと思います。

■質問2
パッと見ですが、
ヘッダーを押したタイミングの時だけソートしたいだけで
リアルタイムにソートされては困るのであれば

computedfilteredHeroesは廃止して
sortByの中にitemsの順番を変更してitemsのプロパティを上書きしてしまう感じでも良さそうですね

投稿2019/12/24 08:24

e-suzuno

総合スコア74

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gichorin

2019/12/27 03:44

ご回答ありがとうございます。 質問1に対する回答ですが、そうとおもいます。 しかし算出プロパティの仕組みが分からないので、これについて調査したいとおもいます。 質問2 廃止してmethodsで作り変えました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問