[Vue] watchフックで連想配列を監視する場合、ディープウォッチャーにしておく必要がある件

# 先に結論のコード
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="riotam4" data-slug-hash="ewvLQJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="watchフックについて(3)">
  <span>See the Pen <a href="https://codepen.io/riotam4/pen/ewvLQJ/">
  watchフックについて(3)</a> by riotam (<a href="https://codepen.io/riotam4">@riotam4</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
```javascript:JS側11行目（ディープウォッチャーの指定部分）
  watch: {
    users: {
      handler: function(){
        alert('変更を検出しました');
      },
      deep: true
    }
  },
```
# 今回したいこと
Vue.jsにはwatchフックという仕組みがあり、指定したデータに変更があった際、仕込んでおいたメソッドを起動してくれます。
便利な仕組みで重宝されますが、watchフックは監視する対象が連想配列の場合、連想配列自体が変更されると検知してくれるのですが、**連想配列の中(要素など)の変更については、検知してくれません。**
以下に具体例を出しながら、今回はこれについて一歩深入りしてみたいと思います。
# 監視対象が単なる文字列の場合
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="riotam4" data-slug-hash="dBvqJR" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="watchフックについて">
  <span>See the Pen <a href="https://codepen.io/riotam4/pen/dBvqJR/">
  watchフックについて</a> by riotam (<a href="https://codepen.io/riotam4">@riotam4</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
入力欄を変更すると、その度に変更を検知して、

```javascript:JS側6行目
  watch: {
    user: function(){
      alert('変更を検出しました');
    }
  },
```
↑が起動して、ダイアログを出します。
ちょっと、うっとしい感じになっちゃってますが…笑
ちゃんと、監視してくれてて、ほぼリアルタイムで検知してくれていることを確認してみてください。
# 監視対象が連想配列で、変更対象がその中の1要素の場合
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="riotam4" data-slug-hash="GbWXYB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="watchフックについて(2)">
  <span>See the Pen <a href="https://codepen.io/riotam4/pen/GbWXYB/">
  watchフックについて(2)</a> by riotam (<a href="https://codepen.io/riotam4">@riotam4</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
次にこちらを試してみてください。
ちゃんと変更の反映はされますが、変更を検知していない様子。
これが、はじめの方にも書かせてもらった、監視できていないパターンです。
これの対策方法が、今回の本題です。
# 対策は「ディープウォッチャー」にすること
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="riotam4" data-slug-hash="ewvLQJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="watchフックについて(3)">
  <span>See the Pen <a href="https://codepen.io/riotam4/pen/ewvLQJ/">
  watchフックについて(3)</a> by riotam (<a href="https://codepen.io/riotam4">@riotam4</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
これが、ディープウォッチャーにしているパターンです。
変更を毎回検知してくれているのが、確認できるかと思います。
具体的に変更を加えるのは、

```javascript:JS側11行目
  watch: {
    users: {
      handler: function(){
        alert('変更を検出しました');
      },
      deep: true
    }
  },
```
ここです。
**処理内容は、hundler部分**に転記して、加えて`deep:true`とすることで、ディープウォッチャーモードにしています。

#結論
watchフックは、Vue.jsでも非常に便利な機能ですが、連想配列などに使う際にはディープウォッチャーモードにできているか、注意が必要。

以上です。
最後ありがとうございました。