こんにちは、シタテルの藤本です。
主にSCS(Sitateru-Control-System)という生産管理システムのバックエンド(Rails)を担当しています。
SCSではRailsでのViewは基本hamlで書かれていますが現在Vueへと移行しようとしています。
最近私もVueを触る機会があり、watchを使用していてハマってしまったところを2点ほど書いておきます。
- Objectをwatchするときはdeepをつけよう
=
で追加してはリアクティブになりませんよ
1. Objectをwatchするときはdeepをつけよう
以下のようにdata(user_name
とusers
)がいて
その値が変更されたことを監視するようにしたい場合にwatchを以下のように書きます
data () {
return {
user_name: '太郎',
users: {}
}
}
watch: {
user_name: function (new_value, old_value) {
alert(`user_name watch!!${this.user_name}`)
},
users: function (new_value, old_value) {
alert(`users watch!!${this.users['name']}`)
}
}
methods: {
changeJiro () {
this.user_name = '二郎'
this.$set(this.users, 'name', '二郎')
},
changeSaburo () {
this.user_name = '三郎'
this.$set(this.users, 'name', '三郎')
}
}
上記の状態でchangeJiro
or changeSaburo
を呼び出すとuser_name
しか監視されません。
Objectを監視したい場合には以下のようにwatchに対してdeep
オプションを付与する必要があります。
users: {
handler: function (new_value, old_value) {
alert(`users watch!!${this.users['name']}`)
},
deep: true
}
公式の以下に記載があります。
watchについて
2. =
で追加してはリアクティブになりませんよ
もう1点ハマったところでObjectの値をセットする際の処理の仕方です。
とほとんど同じ内容ですがmethodsでの
users
へのセットをuser_name
と同様に=
に変更しています。data () { return { user_name: '太郎', users: {} } } watch: { user_name: function (new_value, old_value) { alert(`user_name watch!!${this.user_name}`) }, users: { handler: function (new_value, old_value) { alert(`users watch!!${this.users['name']}`) }, deep: true } } methods: { changeJiro () { alert(`check!! ${this.users['name']}`) this.user_name = '二郎' this.users['name'] = '二郎' //←ここが=でのセットに変わっている }, changeSaburo () { alert(`check!! ${this.users['name']}`) this.user_name = '三郎' this.users['name'] = '三郎' //←ここが=でのセットに変わっている } }
こちらも同様にchangeJiro
or changeSaburo
を呼び出すとuser_name
しか監視されません。
ただしusers['name']
を確認してみると値はセットされています。
原因としてはVue.jsはプロパティの追加または削除を検出できず、リアクティブになっていないため監視できないとのことです。
対応方法としてはわかっているもので2つあります。
- 最初から定義しておく
set
にて追加を行う
1. 最初から定義しておく
Objectのプロパティを最初から定義しておくことで監視することが出来るようになります。
dataに定義しているusers
を以下のように修正します。
users: { name: '太郎' }
2. set
にて追加を行う
こちらは1. に書いてある通りで、methodを以下のように修正します。
changeJiro () {
this.user_name = '二郎'
this.$set(this.users, 'name', '二郎')
},
changeSaburo () {
this.user_name = '三郎'
this.$set(this.users, 'name', '三郎')
}
もっと詳細については以下をご参照ください。
リアクティブの探求
また配列に関しても同様の注意が必要で以下に詳しく書かれております。
配列の変化を検出
終わりに
1人でわりといい時間考え込んでましたが周りに聞いたら即解決しました。
悩みすぎるのはよくないと反省すると共に心強い味方がいることに大変感謝した次第です。
またVueの公式は大変日本語でも充実しているのでしっかり読もうと思いました。
以上です、これからVueをご利用される方の助けになれば幸いです。