Vuexの状態がデータではなくコンポーネントの計算されたプロパティに配置されるのはなぜですか?

Vuexの状態でデータを使用する方法

参照:vuexの状態でデータを使用する4つの方法

  1. Vuexに格納されているデータとVueインスタンスのデータは同じルールに従います。データはどのようなルールに従いますか?
    • タイプ:オブジェクト|関数、コンポーネントの定義は関数のみを受け入れます
    • Vueが再帰的に変換するdataにはプロパティをgetter/setterそうすることを、dataプロパティはデータ変更に対応することができます
    • var vm = new Vue({ data: {a : 1})vm.$data元のデータオブジェクトにアクセスできます。Vueの例は、オブジェクトプロパティのすべてのデータも表すため、access vm.aと同等のアクセスになりますvm.$data.a

参照:Vueのコンポーネントのデータが関数であるのはなぜですか?
Vueコンポーネントは再利用可能なvueインスタンスです。コンポーネントが再利用される回数に関係なく、コンポーネント内のdataデータ互いに分離され、互いに影響を及ぼさないようにする必要があるため、次のことを確認する必要があります。コンポーネントを再利用するたびに、コンポーネントdata内のデータを1回コピーする必要があります。されるdata機能として書き込まれ、データは、部品が再利用されるたびに、新しいものが返されるように、関数の形で返されますdata

  1. Vuexの状態ストレージは応答性が高いため、ストアインスタンスから状態を読み取る最も簡単な方法は、計算された属性状態に戻る
// 创建一个 Counter 组件
const Counter = {
  template: `<div>{
   
   { count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

store.state.count変更があるたびに、計算された属性が再計算され、関連するDOMが更新されます。
**欠陥:**モジュラービルドシステムでは、状態を使用する必要があるすべてのコンポーネントを頻繁にインポートする必要があり、コンポーネントをテストするときに状態をシミュレーションする必要があります

  1. storeオプションを介してVuex はルートコンポーネントから各サブコンポーネント(と呼ばれる必要がありますVue.use(Vuex))に状態を「注入」するメカニズムを提供しますルートインスタンスにstoreオプションを登録すると、ストアインスタンスがルートコンポーネントの下のすべてのサブコンポーネントに注入され、サブコンポーネントにthis.$storeアクセスできます。
const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})
const Counter = {
  template: `<div>{
   
   { count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

プロジェクト内の自分:
main.js、最初にimport store from './store'、次に

new Vue({
  router,
  store,   
  render: h => h(App),
}).$mount('#app')

ストア内index.js
ここに画像の説明を挿入
追加:vue $ mountとelの違い

** 2つの効果に違いはありません。どちらも、インスタンス化されたVueを​​指定されたDOM要素にマウントします。** vueがインスタンス化されるときにelが指定されている場合、vueはこのelに対応するdomにレンダリングされます。逆に、elが指定されていない場合、vueインスタンスは「アンマウント」状態になります。 $ mountを使用して手動でマウントを実行できます。

状態のデータがデータではなく計算済みコンポーネントに配置されるのはなぜですか

参照:vuexの状態を取得するために、データの代わりに計算を使用する理由は何ですか?
これは、データのコンテンツが、作成されたフックがトリガーされる前に一度だけ初期化されるためです。具体的にcount: this.$store.state.countは、countの値はthis.$store.state.count作成されたフックが実行される前にデータ設定されます。割り当て後、属性の値は純粋にリテラルであり、その後のthis.$store.state.count変更はcountの値に影響しません。計算は==依存関係の追跡==によって行われ、計算された属性は、関連する依存関係が変更されたときに再評価されます。

詳細な応答原理を組み合わせて、計算されたデータとライフフックを理解する

***データ***に関して、
Vueは配列とオブジェクトの変更を検出できません

  1. オブジェクトに関して、Vueはプロパティの追加または削除を検出できません。Vueはインスタンスの初期化時にプロパティでゲッター/セッター変換を実行するため、Vueがプロパティをリアクティブに変換するには、プロパティがデータオブジェクトに存在する必要があります
  • すでに作成されているインスタンスの場合、** Vueではルートレベルのレスポンシブプロパティを動的に追加することはできません。**使用することができVue.set(object, propertyName, value)、たとえば、Vue.set(vm.someObject, 'b', 2)も使用することができ、vm.$set例えば、this.$set(this.someObject,'b',2)
  1. 配列に関して、Vueは次の配列の変更を検出できません。
    • インデックスを使用して配列項目を直接設定すると、vm.items[indexOfItem] = newValue
    • 配列の長さを変更すると、vm.items.length = newLength
    • 質問1では、次を使用できます:(Vue.set(vm.items, indexOfItem, newValue)つまりVue.set)またはvm.items.splice(indexOfItem, 1, newValue)(つまりArray.prototype.splice)またはvm.$set(vm.items, indexOfItem, newValue)(つまりvm。$ set)
    • 質問2については、使用することができますsplicevm.items.splice(newLength)
  2. キューを非同期に更新します
    • VueはDOMを非同期で更新します。データの変更をリッスンしている限り、Vueはキューを開き、同じイベントループで発生するすべてのデータ変更をバッファします。同じウォッチャーが複数回トリガーされた場合、キューに1回だけプッシュされます。
    • 次のイベントループ「ティック」で、Vueはキューを更新し、実際の(重複排除された)作業を実行します。Vueは、非同期キューに対してネイティブのPromise.then、MutationObserver、およびsetImmediateを内部で使用しようとします
    • データの変更後にVueがDOMの更新を完了するのを待つために、データが変更された直後にVue.nextTick(callback)を使用できます。このように、コールバック関数はDOMの更新が完了した後に呼び出され、$ nextTick()はPromiseオブジェクトを返します

***計算済み***について、

  • 計算されたプロパティにはデフォルトでゲッターのみがあり、副作用はありません
  • メソッドと計算された属性として同じ関数を定義します。再レンダリングがトリガーされると、呼び出し側のメソッドは常に関数を再度実行します。**計算された属性は、応答する依存関係に基づいてキャッシュされます。**関連する事後依存関係が変更された場合にのみ再評価されます。Vuexでは、ゲッターの戻り値は依存関係に従ってキャッシュされ、依存関係の値が変更された場合にのみ再計算されます。
  • なぜキャッシュが必要なのですか?パフォーマンスオーバーヘッドが比較的大きい計算属性Aがあるとします。これは、巨大な配列をトラバースし、多くの計算を実行する必要があります。次に、Aに依存する他の計算されたプロパティがある場合があります。キャッシュがない場合、必然的にAのゲッターを複数回実行します!
  • 監視属性watchを使用すると、watchは、データが変更されたときに非同期または高価な操作を実行する必要がある場合に最も役立ちます。

おすすめ

転載: blog.csdn.net/weixin_43912756/article/details/108429404