5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Vue.js]配列の変更が検知できない理由の「JavaScriptの制限」って何よ!

Last updated at Posted at 2020-02-04

タイトルのJavaScriptの制限はこちらに記載されているものです。
リストレンダリング(注意事項) — Vue.js

要約すると、
配列に対して直接インデックスの設定、またはlengthプロパティを変更する場合、viewは更新されません。

具体的な操作はこちら。

インデックスでアイテムを直接設定するとき。例: vm.items[indexOfItem] = newValue
配列の長さを変更するとき。例: vm.items.length = newLength

その回避策が Vue.setArray.prototype.splice を使用するというものです。
簡単にできる回避策なので、ふーんって感じで書き換えて終了なのですが、
JavaScriptの制限が気になったので調べてみました。

ざっくり リアクティブシステム

Vue.jsの値の変更の検知の仕組みは、リアクティブシステム1で実現されています。
ざっくり言うと、Vueインスタンス化の際にプロパティに対してリアクティブになるよう、よしなにやってくれるシステムです。

data.png

こちらの図でいうと、プロパティの変更をgetter/setterをトリガーにしてWatcherで再描画してくれているということです。

んで、JavaScriptの制限って何さ!

ヒントはここに書いてありました。
リストレンダリング(配列の置き換え) — Vue.js

例えば、filter()、concat()、そしてslice() のような、元の配列を変更しませんが、常に新しい配列を返します。

リアクティブシステムは新しい配列を返してくれることを望んでいるんです!

つまり

JavaScriptの制限というのは、新しい配列を返さない操作のことを言っているのです。

vm.items[indexOfItem] = newValuevm.items.length = newLengthも配列を返しません。

なんだそれだけなのか

それだけなんです。
リストレンダリング(変更メソッド) — Vue.js
ここに書かれているメソッドは新しい配列を返すから検知できるんです。

まとめ

私の日本語を読む能力が低かったせいで、
JavaScriptの制限が配列の置き換えの章に掛かっていることに気づくのに時間がかかってしまいました。(汗)

お間違い等ございましたら、ご指摘いただけますと幸いです。:bow:

  1. リアクティブの探求 — Vue.js

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?