5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Vue.js】オブジェクトをwatchした時、fromとtoで同じオブジェクトが帰ってきていた

Last updated at Posted at 2019-07-25

プロパティをまとめて監視したかったのでオブジェクトを用意して監視していたのですが、表題のところでつまづきました。
解決したので備忘録です。

watchのおさらい

index.html
<div id="app">
    <input type="text" v-model="num">
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            num: 0,
        },
        watch: {
            num: {
                handler: function(to, from) {
                    console.log(from + ' -> ' + to);
                }
            },
        },
    })
</script>

numを監視して、変更前と変更後をconsoleに吐き出す簡単なアプリケーションです。
ここまではなんの問題もなく動きます。

オブジェクトを監視するとうまく動かない

index.html
<div id="app">
    <input type="text" v-model="obj.num">
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            obj: {
                num: 0,
            }
        },
        watch: {
            obj: {
                deep: true, // オブジェクト内のプロパティを監視対象に含めるためdeepをtrueに
                handler: function(to, from) {
                    console.log(from.num + ' -> ' + to.num);
                }
            },
        },
    })
</script>

上記のように記述した場合、obj.numを変更してもconsoleには変更前と変更後に同じ値が出力されてしまいました。
シャローコピーされた値が帰ってきているためこのような現象になるのだと思います。

算出プロパティを監視して解決

index.html
<div id="app">
    <input type="text" v-model="obj.num">
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            obj: {
                num: 0,
            }
        },
        computed: {
            computedObj: function() {
                return Object.assign({}, this.obj); // ディープコピーしたものを返す
            },
        },
        watch: {
            computedObj: { // 算出プロパティを監視
                deep: true,
                handler: function(to, from) {
                    console.log(from.num + ' -> ' + to.num);
                }
            },
        },
    })
</script>

ディープコピーした値を返す算出プロパティを用意し、その算出プロパティを監視するようにしました。

fromとtoは別参照のオブジェクトになったため無事正しいオブジェクトが帰ってきました。

参考:https://github.com/vuejs/vue/issues/2164

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?