watch
やcomputed
を使ってデータを監視するときにいろいろ大変だったのでメモ。
vueではdata
やcomputed
にあるデータを監視して、変更を検知して何かしらfunctionを起こしたりとかが出来る。
今回やりたいこと
props[quote]
の変更を検知して、quote_controllerにPOSTしたい。
ただし、quote
の中にはquote.choices
とquote.room
がある。
元の状態
watch: {
quote: {
handler: function(newValue) {
this.$http.post('//localhost:3000/quote', {
choices: this.choices,
room: this.room
}).then((res) => {
this.quote.sections = res.data
})
},
deep: true
}
}
何が問題なの?
handler
をつけると、配列の要素そのものが変更されたことを検知する。つまり、this.room = room1 => this.room = room2
とか、this.choicesの要素の一つの内容だけ変わったとかも検知してくれる。deep: true
がないと、配列の要素の増減は検知してくれるけれど内容が変わったことは検知しない。
今回、room
に関しては内容の変更も検知してもらう必要がある。でないとroomに入っているのはいつも一つの要素だけだから永遠に検知されない。
でも、choices
に関してはpattern
を変更すると一気に要素が入れ替わる為、その時に要素が変わったのをいちいち検知して永遠にPOSTされてしまった。
しかし、choices
とroom
は同時にPOSTする必要があるので別々にwatchしてPOSTアクションを起こすことは避けたい…
解決😇?
これで一旦正常に動いているように見える。
watch: {
choices: function(newVal, oldVal) {
this.change = true
console.log("heyyyyyy")
},
room: {
handler: function(newVal, oldVal) {
this.change = true
console.log("wowowowowowo")
},
deep: true
},
change: {
handler: function(newVal, oldVal) {
if(this.change) {
this.$http.post('//localhost:3000/quote', {
choices: this.choices,
room: this.room
}).then((res) => {
this.quote.sections = res.data
})
console.log("www")
this.change = false
}
}
}
}
まず。datachange
を置く。
room
だけdeep: true
の状態にして、choices
とroom
の変更が検知されたらchange=true
としてchange
自体の変更もwatchする。