2018年Vue.jsを使ってる人には知って欲しいオブジェクトと配列の操作のベストプラクティス

# はじめに
基本的に Vue は子要素の代入演算子は感知しません。
しかし、Array は公式が公表している、[ラップした変更検知メソッド](https://jp.vuejs.org/v2/guide/list.html#%E5%A4%89%E6%9B%B4%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)を利用して、操作をすればやりたい事はほぼ全て実現できるでしょう。

これらはAirbnb lint ruleから得られた経験から来た知見です。結構使いやすい。
`;` セミコロンを末尾に付けたくない人も多いと思いますが、そこはruleを上書きすればまぁ良いでしょう。

`push`　や `pop` 程度など、まぁ知ってるでしょうていう軽いのは省いています。

## ゴール
コンポーネントとストアの記法の統一

## 配列辺
### 規定回数繰り返す
よく見るairbnb lintで怒られるコード

```js
for (let i=0;i<5;i++) {
	print(i)
}
```

改善。これはとても見やすいですね。

```js
[...Array(5)].forEach((_, i) => { console.log(i) })
```

ちなみにこれは動きません。

```js
Array(5).forEach((_, i) => { console.log(i) })
```

一応スプレッド演算子が使えない環境ならこんな書き方もあります。
割と見やすい。

```js
Array.apply(null, { length: 10 }).forEach((v, i) => console.log(i))
```

---
### 配列の特定インデックスの値を書き換える
リアクティブにならなくて辛いやつ

```js
a = [{a:1},{b:2}]
a[1].b = 10
```

リアクティブで嬉しいやつ。

```js
a = [{a:1},{b:2}]
a.splice(1, 1, {b:10})
```
#### 軽く解説
spliceはまず開始indexを指定して、そこから何個取り除くのかを指定し、最後に指定した箇所に挿入する要素を渡せます。これはリアクティブでとても嬉しい。
あと、何個取り除くかの個数を0にすれば、単純に要素の挿入になり、とても良い感じです。
また、第３引数を入れなければ、普通に要素削除にもなります。
途中の要素挿入、追加、削除は`splice`とりあえず使えばとても統一感が出そうな気がしますね。

---
### computedやgetterの際のみ、特定要素を追加したい
```js
data() {
	return {
		a: [
			{ name: '田中', age: 22 },
			{ name: '小林', age: 18 },
		],
	}
},
```

これはとても悲しい例ですね。。。
getterで副作用を発生させている。。。悲しい。`store` の `getter` でも `this.a` ならず、`state.a` バージョンを見たことあります。

```js
computed: {
	personList() {
		this.a.forEach(item => {
			item.isMinority = item.age < 20
		})
		return this.a
	},
},
```

改善。[map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)最高！

```js
computed: {
	personList() {
		return this.a.map(item => ({ ...item, isMinority: item.age < 20 }))
	},
},
```
---
### foreach
まぁ、よくみるやつ

```js
const a = [1,2,3]
for (const i in a) {
	console.log(i, a[i])
}

for (const i of a) {
	console.log(i)
}
```

lintで叱られないし、配列っぽくてこっちのが良い気がする

```js
const a = [1,2,3]
a.forEach((value, i) => {
	console.log(i, value)
})

a.forEach(value => {
	console.log(value)
})
```
---
### break foreach
皆さんこういうのやりたいですよね

```js
const a = [44,99,55,33]

for (i of a) {
	if (i === 55) break
	console.log(i)
}
```

これでどうでしょか。some最高！

```js
const a = [44,99,55,33]

a.some(i => {
	if (i === 55) return true
	console.log(i)
})
```

### 配列から特定の値を検索して、それの値を変えたい
よくみるやつ。リアクティブにならなくてとてもかなしい。`Vue.set`使えばいけるけど、storeだと使えないので、記法を統一したいですよね。

```js
const a = [44,99,55,33]

for (i in a) {
	if (a[i] === 55) {
		a[i] = 4649
		break
	}
}
```

これはどうでしょうか。

```js
const a = [44,99,55,33]

const key = a.findIndex(i => i === 55)
if (key !== -1) {
	a.splice(key, 1, 4649)
}
```

### props downしてきた値を算出プロパティで並び替えたい
lodashに依存して楽をする

```js
buttonList() {
	return _.sortBy(this.buttons, button => button.order)
}
```

## オブジェクト辺
### プロパティを上書き・追加する
リアクティブじゃなくてとても悲しいやつ

```js
let a = {
	name: '田中',
	age: 18,
}

a.age = 20
```

これはリアクティブでとても嬉しい

```js
let a = {
	name: '田中',
	age: 18,
}

a = { ...a, age: 20 }
```

### プロパティを削除する
リアクティブじゃなくて悲しいやつ

```js
let a = {
	name: '田中',
	type: 'スーパーマン',
	age: 18,
}

delete(a.age)
```

リアクティブで嬉しいやつ。

```js
let a = {
	name: '田中',
	type: 'スーパーマン',
	age: 18,
}

let clone = { ...a }
delete(clone.age)
a = clone
```

## 最後に
如何だったでしょうか？
統一された良いコードを頑張って作っていきましょう！