概要
こういう配列番号を直指定で上書く書き方よくやるんだけど、Vueを使用してる時はしてはいけない。
js
var test_array = [1, 2, 3, 4]
test_array[1] = 5 // [1, 5, 3, 4]
なぜか。
それは算出プロパティが正しく動かなくなるからである。
何があった?
リストの編集機能とかよく作るじゃない。
で、編集用の子コンポーネントモーダル作って、編集したらプレビューさせる親コンポーネントに表示するとする。
親コンポーネントに表示する際、
- プレビュー用の値
- サーバ送信用のhiddenのname/value
を更新したいとすると、子コンポーネントから受け取った値を加工したい場合もあって、
算出プロパティ使って多少処理をいれたりするじゃない。
その際、編集時の処理で親コンポーネントで配列の値を直指定で更新してました。
コードはこんな感じ。
sample.coffee
Vue.component('child_component', {
template: '#child_template'
method:
setOption: (value, index)-> # [1]編集時にこのメソッドを呼び出す
hub.$emit 'set-option', value, index
})
Vue.component('parent_component', {
template: '#parent_template'
data: ->
{ return options: [] }
computed:
computed_options: -> # [3]ここで、optionsが変更された際に再評価してほしいが、されない・・!
# ここでoptions使ってdisp_optionsを用意する
return disp_options
created: ->
self = @
hub.$on "set-option", (value, index) ->
self.options[index] = value # [2]optionを子コンポーネントの値で更新
})
hub = new Vue()
なぜ?
Vueの公式サイトにこう書いてあった。
JavaScript の制限のため、Vue は配列で以下の変更を検出することはできません
1. インデックスでアイテムを直接設定するとき。例: vm.items[indexOfItem] = newValue
なんてこった。。。
どうしたら?
こうしたら良いのだって。
pattern1.js
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
pattern2.js
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)
予想外にハマって時間取られました。。。
どうやって解決した?
時間かかってどうしようもなかったのでここで質問しました。
https://vuejs-jp-slackin.herokuapp.com/
質問してから30分程度で解決しました。
ありがとうございました!!!!!