この記事は,[ ](https://.to/blacksonic/you-might-not-need-vuex-with-vue-3-52e4)
Vuexは素晴らしい状態管理ライブラリです。シンプルで、Vueとうまく統合されています。一部の人々がVuexを放棄している理由は、おそらく次期Vue3がアプリケーションを整理する新しい方法であるreactivityシステムを公開するからでしょう。新しいリアクティビティシステムはとても強力で、一元的な状態管理に使用することができます。
ステータスを共有する必要がありますか?
複数のコンポーネントのデータフローを一元的に管理することが難しいシナリオもあります:
- 複数のコンポーネントが同じデータを使用
- 複数のルートノードのデータアクセス
- 深くネストされたコンポーネント
上記のシナリオに遭遇したことがないのであれば、Vuexが必要かどうかは別として、答えは明白です。
しかし、このようなシナリオに遭遇した場合、最も簡単な答えはVuexを使用することです。
他の三方向の依存関係を追加したくない、またはVuexのソリューションが複雑すぎると感じますか?新しいVue3バージョンでは、composition-apiの組み込みメソッドを使用してこれらの問題を解決できます。
新しいシナリオ
シェアード・ステータス・プログラムが満たすべき基準は2つあります:
- レスポンシブ:共有状態が変更されると、コンポーネントで使用されている部品も更新する必要があります。
- 高可用性:共有状態はどのコンポーネントでもアクセスできます。
レスポンシブ
Vue3は、多くの関数を通してレスポンシブ・システムを公開しています。reactivity関数を使用すると、レスポンシブな変数を作成できます。
import { reactive } from 'vue';
export const state = reactive({ counter: 0 });
このリアクティブ関数によって返されるオブジェクトは、自身のプロパティの変更を追跡する Proxy オブジェクトです。コンポーネントのテンプレートで使用される場合、コンポーネントはレスポンシブデータの変更に基づいて再レンダリングされます。
<template>
<div>{{ state.counter }}</div>
<button type="button" @click="state.counter++">Increment</button>
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({ counter: 0 });
return { state };
}
};
</script>
高い可用性
上記の例は、単一のコンポーネントに対してはうまく機能しますが、他のコンポーネントはステートにアクセスできません。これを回避するには、provideメソッドとobjectメソッドを使用して、Vue3アプリの内部で利用可能な値を作成します。
import { reactive, provide, inject } from 'vue';
export const stateSymbol = Symbol('state');
export const createState = () => reactive({ counter: 0 });
export const useState = () => inject(stateSymbol);
export const provideState = () => provide(
stateSymbol,
createState()
);
Symbolタイプのキー値をprovideメソッドに渡すと、この値はobjectメソッドを介してどのサブコンポーネントでも使用することができます。Symbolタイプのキー名を使用すると、対応する値を取得するために使用されます。
このソリューションでは、最上位のコンポーネントで値を提供する場合、その値はすべてのコンポーネントで利用可能になります。あるいは、アプリケーションインスタンスエントリのメインの
import { createApp, reactive } from 'vue';
import App from './App.vue';
import { stateSymbol, createState } from './store';
const app = createApp(App);
app.provide(stateSymbol, createState());
app.mount('#app');
<script>
import { useState } from './state';
export default {
setup() {
return { state: useState() };
}
};
</script>
改善方法
上記のシナリオは機能しますが、欠点があります。状態は、何の制限もなく、すぐに変更できます。
readonly関数はプロテクトされた状態に対して使用できます。これはProxy変数オブジェクトへの変更をブロックするために使用できます。ステートへの変更は、それを管理する権限を持つ関数に抽象化されるべきです。
import { reactive, readonly } from 'vue';
export const createStore = () => {
const state = reactive({ counter: 0 });
const increment = () => state.counter++;
return { increment, state: readonly(state) };
}
これにより、外部からアクセスできるのは読み取り可能な状態のみとなり、状態を変更するための関数はわずかしか公開されません。
状態変更の保護を備えた新しいソリューションは、Vuexに近いものです。
要約すると
読み取り専用の状態オブジェクトがあり、テンプレート内で反応します。この状態は、Vuexのアクション/変異のような特別な関数によってのみ変更できます。また、computed関数によってゲッターをカスタマイズすることもできます。
Vuexには、モジュール管理など、より多くの機能がありますが、不要な場合もあります。





