#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。理由: 複数のコンポーネント インスタンス オブジェクトが同じデータを共有してデータ汚染を引き起こすのを防ぐため、関数の形式で initData がファクトリ関数として使用されると、新しいデータ オブジェクトが返されます。コンポーネント内のデータを関数として記述する場合、データは関数の戻り値の形式で定義されるため、コンポーネントが再利用されるたびに、プライベート データを作成するのと同様に、独自のスコープを持つ新しいデータが返されます。データ空間により、各コンポーネント インスタンスは独自のデータを維持できます。
1. インスタンス定義データとコンポーネント定義データの違い
vue インスタンスを定義する場合、データ属性はオブジェクトまたはFunctionconst app = new Vue({ el:"#app", // 对象格式 data:{ foo:"foo" }, // 函数格式 data(){ return { foo:"foo" } } })
Vue.component('component1',{ template:`<div>组件</div>`, data:{ foo:"foo" }})
#2. コンポーネント データ定義関数とコンポーネント データ定義関数の違いオブジェクト##コンポーネント データは関数でなければならないと上で述べましたが、なぜそうなるのか考えたことはありますか?
コンポーネントを定義すると、Vue は最終的に Vue.extend() を通じてコンポーネント インスタンスを形成します。
ここでは、コンポーネント コンストラクターを模倣し、データ属性を定義し、オブジェクトの形式を採用します。
function Component(){ } Component.prototype.data = { count : 0 }
2 つのコンポーネント インスタンスを作成します
const componentA = new Component() const componentB = new Component()
componentA コンポーネントのデータ属性の値を変更すると、componentB の値も変更されます
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 1
その理由は次のとおりです。同じメモリ アドレスで、componentA によって変更された内容は、componentB にも影響します。 [学習ビデオ共有:
vue ビデオ チュートリアル、Web フロントエンド ビデオ ]関数の形式を使用する場合、これは起こりません (オブジェクトが返されます)関数によるメモリアドレスは同じではありません)
function Component(){ this.data = this.data() } Component.prototype.data = function (){ return { count : 0 } }
componentA コンポーネントの data 属性の値を変更します。componentB の値は影響を受けません
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 0
vue コンポーネントは、多くのインスタンスがあり、各インスタンス オブジェクトのデータが他のインスタンス オブジェクトのデータによって汚染されないように、この関数は新しいデータ フォームを返すために使用されます (
3)。分析まず最初に、Vue がデータ コードを初期化することを見てみましょう。データの定義は関数またはオブジェクトにすることができます。
ソース コードの場所:
/vue-dev/src/core/instance/state.js<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === &#39;function&#39;
? getData(data, vm)
: data || {}
...
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
data はオブジェクトと関数の両方である可能性があるのに、なぜ上記の警告が表示されるのでしょうか?
心配しないで、以下を読み続けてください。
コンポーネントが作成されると、オプションはマージされます
ソースコードの場所:
/vue-dev/src /core/ util/options.jsカスタマイズされたコンポーネントはオプションのマージのために mergeOptions に入ります
Vue.prototype._init = function (options?: Object) { ... // merge options if (options && options._isComponent) { // optimize internal component instantiation // since dynamic options merging is pretty slow, and none of the // internal component options needs special treatment. initInternalComponent(vm, options) } else { vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm ) } ... }
データを定義するとデータ検証が実行されます
ソース コードの場所:
/ vue-dev/src/core/instance/init.jsこの時点では vm インスタンスは未定義のため if 判定に入り、データ型が関数でない場合は警告が表示されます。出現
strats.data = function ( parentVal: any, childVal: any, vm?: Component ): ?Function { if (!vm) { if (childVal && typeof childVal !== "function") { process.env.NODE_ENV !== "production" && warn( 'The "data" option should be a function ' + "that returns a per-instance value in component " + "definitions.", vm ); return parentVal; } return mergeDataOrFn(parentVal, childVal); } return mergeDataOrFn(parentVal, childVal, vm); };
4. 結論ルート インスタンスのオブジェクト データはオブジェクトまたは関数 (ルート インスタンスはシングルトン) にすることができます。データ汚染を引き起こしません
コンポーネント インスタンス オブジェクトのデータは関数でなければなりません。目的は、複数のコンポーネント インスタンス オブジェクトが同じデータを共有してデータ汚染を引き起こすことを防ぐことです。関数の形式では、initData が新しいデータ オブジェクトを返すときにファクトリ関数として使用されます。
説明:
(学習ビデオ共有: Web フロントエンド開発、基本プログラミング ビデオ)
以上がvue コンポーネント内のデータが関数なのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。