Props with type Object/Array must use a factory function to return the default value
Props with type Object/Array must use a factory function to return the default value:
あなたがこの記事を見ているということは、コンソールに以下のワーニングが出ていることでしょう。
このワーニングはVueコンポーネントの
「propsのdefaultの値にObjectやArrayを使用したい場合、ファクトリー関数を指定しろ」
という内容のワーニングです。
以下のようにコードを修正することでワーニングを解消できます。
なぜ、ObjectやArrayをデフォルト値としたい場合、関数を指定する必要があるのでしょうか。
まず、ワーニングを無視した場合に何が起こるのか試してみます。
「+1」ボタンのクリックでカウンターをインクリメントする、Vueコンポーネントです。
そのカウンターを2つ配置して動かしてみると、以下のような結果になります。
どちらのボタンをクリックしても、2つのカウンターがインクリメントされています。
↓のリンクから実際に触っていただけます。
propsのデフォルト値に指定したオブジェクトや配列は、値がコピーされることなく参照が共有されます。
そのため、複数のvueインスタンスが同一のObjecを参照し、同一のObjectに変更を加えてしまう状況が発生します。
2つのカウンターがどちらのボタンの操作でもインクリメントされるのは、このためです。
ワーニングを出すのではなく、フレームワーク側でObjectや配列を自動でディープコピーしてくれればいいのでは?と考えることもできるのですが、開発者側で
ファクトリー関数を指定できるようにすることで、ディープコピーにまつわるリスクを抑えつつ、実装の選択肢を広げ自由度を上げる目的があるようです。
https://github.com/vuejs/vue/issues/1032
あなたがこの記事を見ているということは、コンソールに以下のワーニングが出ていることでしょう。
WARN
[Vue warn]: Invalid default value for prop "XXX": Props with type Object/Array must use a factory function to return the default value.
props
に関するものです。「propsのdefaultの値にObjectやArrayを使用したい場合、ファクトリー関数を指定しろ」
という内容のワーニングです。
ワーニングを解消する
以下のようにコードを修正することでワーニングを解消できます。
修正前
props: { obj: { type : Object, require : false, 'default': { count: 0 } // Objectをそのまま指定している }, }
修正後
props: { obj: { type : Object, require : false, 'default': () => ({ count: 0 }) // Objectを生成する関数を指定する }, }
なぜ関数を指定する必要があるのか
なぜ、ObjectやArrayをデフォルト値としたい場合、関数を指定する必要があるのでしょうか。
ワーニングを無視すると何が起こるか
まず、ワーニングを無視した場合に何が起こるのか試してみます。AppCounter.vue
<template> <div class="content"> <span>{{ obj.count }}</span> <button @click="obj.count++;">+1</button> </div> </template> <script> export default { props: { obj: { type: Object, require: false, 'default': { count: 0 } // ワーニングを無視して、Objectをそのまま指定している } } }; </script>
App.vue
<template> <div id="app"> <app-counter /> <app-counter /> </div> </template> <script> import AppCounter from "./components/AppCounter"; export default { name: "App", components: { AppCounter } }; </script>
どちらのボタンをクリックしても、2つのカウンターがインクリメントされています。
↓のリンクから実際に触っていただけます。
オブジェクトや配列は値がコピーされず、参照が共有される
propsのデフォルト値に指定したオブジェクトや配列は、値がコピーされることなく参照が共有されます。そのため、複数のvueインスタンスが同一のObjecを参照し、同一のObjectに変更を加えてしまう状況が発生します。
2つのカウンターがどちらのボタンの操作でもインクリメントされるのは、このためです。
ワーニングを出すのではなく、フレームワーク側でObjectや配列を自動でディープコピーしてくれればいいのでは?と考えることもできるのですが、開発者側で
ファクトリー関数を指定できるようにすることで、ディープコピーにまつわるリスクを抑えつつ、実装の選択肢を広げ自由度を上げる目的があるようです。
コメント
コメントを投稿