オブジェクトに新しいプロパティの追加・削除（Vue.js)

今回はアドベントカレンダーっぽく、面白い記事を書きたい！と思っていましたが、~~ネタが出てこず（笑 )~~だったので、いつも自分が忘れてしまうVue.jsでオブジェクトに新しくプロパティを追加・削除する方法をアウトプットします。ご了承くださいませ:santa:


### はじめに
Vue.jsは、dataやpropsの変更を検知して、自動的にDOMに反映してくれます。ですが、変更を検知できない追加方法があり、その方法でオブジェクトの追加をしてしまうとDOMに反映されません。

###変更検出の注意事項
[リアクティブの探求](https://jp.vuejs.org/v2/guide/reactivity.html#%E5%A4%89%E6%9B%B4%E6%A4%9C%E5%87%BA%E3%81%AE%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85)
>Vue はプロパティの追加または削除を検出できません。Vue はインスタンスの初期化中に getter/setter の変換を行うため、全てのプロパティは Vue が変換してリアクティブにできるように data オブジェクトに存在しなければなりません

オブジェクトの中に新しいキーと値を直接代入しても、 Vue.jsはそれを監視できない為、値の更新や再描写ができません。下記のサンプルコードをご覧ください。


```Hoge.vue
<template>
  <div>
    <button @click="onClickedButton">追加</button>
    <p
      v-for="value in object"
      :key="value.id">
      {{ value }}
    </p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      object: {
        id: 1,
        name: 'hoge',
      },
    };
  },
  methods: {
    onClickedButton() {
      this.object.age = 30 //この追加方法では、検知機構がないプロパティになってしまう
    },
  },
};
</script>
```

ボタンを押して後にVue.js devtoolsでdataの内容を確認してみても、オブジェクトの中にageというキーと30の値が入っていない状態です。
![スクリーンショット 2020-12-12 14.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/f0343bd5-7f6a-03b4-3ef0-8f0d81281e4b.png)


### 解決方法
---
### ・一つのキーを追加する場合は、this.$setを使用する
```javascript

this.$set(this.object, 'age', 30)
```
第一引数はキーを<font color="OrangeRed">追加したいオブジェクト</font>、第二引数は<font color="OrangeRed">キー名</font>、第三引数は<font color="OrangeRed">値</font>を指定してあげます。vm.$setインスタンスメソッドを使用してあげることで、リアクティブなプロパティを追加することができます。

上記のサンプルコードの記述を変更してVue.js devtoolsで確認してみると、
![スクリーンショット 2020-12-12 14.59.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/cda39e96-77d8-b38b-95af-110d7e5cd4a9.png)

はい、オブジェクトの中にageというキーと30の値が入っていることが確認できます。また、ブラウザ画面でも反映されています。

### ・1.複数のキーを追加する場合は、新しいオブジェクトを作成する(スプレッド構文を使用)

```javascript
const newObject = {
  age: 30,
  country: 'Japan'
}
this.object = { ...this.object, ...newObject }
```
上記は、スプレッド構文を使用してobjectとnewObjectのそれぞれを展開して、マージした後に再度、objectの代入をしています。こちらで複数のプロパティが追加できます。

![スクリーンショット 2020-12-12 16.04.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507371/31d70553-0f8b-9ac0-522b-ad3cf9eb8eb2.png)
ageとcountryのキーと値が無事に追加できていることが確認できます。

スプレッド構文について知りたい方がいましたら、他の方が書かれた分かりやすい記事がありましたので、参考文献としてリンクを貼っております↓
[JSのスプレッド構文を理解する](https://qiita.com/akisx/items/682a4283c13fe336c547)


### ・2.複数のキーを追加する場合は、新しいオブジェクトを作成する(Object.assignを使用)
スプレッド構文を使用しない場合は、

```javascript
const newObject = {
  age: 30,
  country: 'Japan'
}
this.object = Object.assign({}, this.object, newObject)
```
第一引数は<font color="OrangeRed">空のオブジェクト</font>、第二引数と第三引数には<font color="OrangeRed">既存のオブジェクトと新しいオブジェクト</font>を指定してあげます。
こちらでもスプレッド構文を使用した時と同様の結果になります。

個人的には、下記の理由からスプレッド構文を使用する方が良いかなと思っています。
・スプレッド構文の方がモダンかつスッキリと書ける
・Object.assignはIEではサポートしていない


また、下記にはスプレッド構文とObject.assignの違いについて書かれてある記事のリンクを貼っておきますので、ご興味ある方はぜひどうぞ🙇‍♂️
 [Object.assign({},obj)と{...obj}の違い](https://qiita.com/uhyo/items/eaed00f1af9b0b7ee2e6)


では、最後にプロパティを削除する方法です。
### ・プロパティの削除は、this.$deleteを使用する
```javascript

this.$delete(this.object, 'name')
```
第一引数は<font color="OrangeRed">オブジェクト</font>、第二引数は<font color="OrangeRed">削除したいプロパティのキー名</font>
を指定してあげます。
こちらでプロパティの削除ができます。

はい、以上になります。


### おわりに
見てくださった方ありがとうございます！
もし誤字・脱字等ありましたらご指摘頂けると嬉しいです:writing_hand_tone1:
よろしくお願いいたします。
来年こそは、アドベントカレンダーらしいネタ記事が書けたらいいな〜🐱