vue コンポーネント内のデータが関数なのはなぜですか?

青灯夜游
リリース: 2022-12-01 20:25:45
オリジナル
11783 人が閲覧しました

理由: 複数のコンポーネント インスタンス オブジェクトが同じデータを共有してデータ汚染を引き起こすのを防ぐため、関数の形式で initData がファクトリ関数として使用されると、新しいデータ オブジェクトが返されます。コンポーネント内のデータを関数として記述する場合、データは関数の戻り値の形式で定義されるため、コンポーネントが再利用されるたびに、プライベート データを作成するのと同様に、独自のスコープを持つ新しいデータが返されます。データ空間により、各コンポーネント インスタンスは独自のデータを維持できます。

vue コンポーネント内のデータが関数なのはなぜですか?

#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。

1. インスタンス定義データとコンポーネント定義データの違い

vue インスタンスを定義する場合、データ属性はオブジェクトまたはFunction

const app = new Vue({
    el:"#app",
    // 对象格式
    data:{
        foo:"foo"
    },
    // 函数格式
    data(){
        return {
             foo:"foo"
        }
    }
})
ログイン後にコピー

コンポーネントで定義されているデータ属性は関数のみです

コンポーネント データがオブジェクトとして直接定義されている場合

Vue.component('component1',{
    template:`<div>组件</div>`,
    data:{
        foo:"foo"
    }})
ログイン後にコピー

、警告メッセージが表示されます

vue コンポーネント内のデータが関数なのはなぜですか?

警告: 返されるデータは、各コンポーネント インスタンスの関数である必要があります

#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 === &amp;#39;function&amp;#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(
          &#39;The "data" option should be a function &#39; +
            "that returns a per-instance value in component " +
            "definitions.",
          vm
        );
      return parentVal;
    }
    return mergeDataOrFn(parentVal, childVal);
  }
  return mergeDataOrFn(parentVal, childVal, vm);
};
ログイン後にコピー

4. 結論ルート インスタンスのオブジェクト データはオブジェクトまたは関数 (ルート インスタンスはシングルトン) にすることができます。データ汚染を引き起こしません

コンポーネント インスタンス オブジェクトのデータは関数でなければなりません。目的は、複数のコンポーネント インスタンス オブジェクトが同じデータを共有してデータ汚染を引き起こすことを防ぐことです。関数の形式では、initData が新しいデータ オブジェクトを返すときにファクトリ関数として使用されます。

説明:

    vue のコンポーネントは再利用可能ですが、データの再利用を防ぐために関数として定義します。
  • vue コンポーネント内のデータは互いに分離され、相互に影響を及ぼさないようにする必要があります。コンポーネントを再利用するたびに、データ データを 1 回コピーする必要があります。ある場所を再利用する 使用しているローカルコンポーネントのデータデータが変更されても、他の再利用ローカルコンポーネントのデータデータには影響しないため、data関数を通じてコン​​ポーネントの状態としてオブジェクトを返す必要があります。
  • コンポーネント内のデータを関数として記述すると、データは関数の戻り値の形式で定義されるため、コンポーネントが再利用されるたびに新しいデータが生成されます。独自のスコープを持つ返されることは、コンポーネント インスタンスごとにプライベート データ スペースを作成することに似ており、各コンポーネント インスタンスが独自のデータを維持できるようになります。
  • コンポーネントの日付を単純にオブジェクト形式で記述すると、これらのインスタンスは同じコンストラクターを使用しますが、JavaScriptの特性上、すべてのコンポーネントインスタンスは1つのデータを共有するため、すべてを変える結果に。

(学習ビデオ共有: Web フロントエンド開発基本プログラミング ビデオ)

以上がvue コンポーネント内のデータが関数なのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート