vuex と永続性の使用
この記事では主に vuex の使い方と状態を永続化する方法の詳細な説明を紹介しますので、参考にしてください。
Vuex は、Vue.js アプリケーション専用に開発された状態管理パターンです。集中ストレージを使用してアプリケーションのすべてのコンポーネントのステータスを管理し、対応するルールを使用してステータスが予測可能な方法で変化することを保証します。
私たちが vuex に出会ったとき、これが最初に見た公式のガイダンスでした。
この文から次の情報が得られます:
1. vuex は vue に特化した Flux であり、vue なしでも vuex を使用できます。逆に、reduxは存在せず、vueでもreactでもreduxが使えることがわかります。 vuex の「機能」はここに反映されており、redux には「汎用性」があります
2. vue 内のすべてのコンポーネントのステータスが vuex に存在することを示す
3。コンポーネントの状態の変化を追跡できます。
1. プロジェクト内の vuex ディレクトリの構築
上の図は、この記事の vue プロジェクト全体のスケルトンの一部です。
vuex は単一の状態ツリーを使用し、vue アプリケーションにはストア インスタンスが 1 つだけ含まれます。したがって、ストアを vue インスタンスにマウントすると、this.$store を通じて vuex のさまざまな部分を取得できます。
2.index.js
import vue from 'vue' import vuex from 'vuex' import mutations from './mutation' import getters from './getter' vue.use(vuex) const state = { isLoading:false } export default new vuex.Store({ state, getters, mutations })
インデックスファイルでは、vuexに保存する必要がある状態の初期値を定義します。
たとえば、上記の状態オブジェクトに isLoading 属性を保存しました。この属性は、バックエンド API をリクエストしたときに表示される読み込み効果を識別するために使用する予定です。これは、リクエストが完了すると表示されなくなります。ユーザーの待ち心理。
3.Mutation (mutation.js)
一般的に、私たちのプロジェクトで最も一般的に使用されるメソッドは、mutation.js のメソッドです。 vuex でストアの状態を変更する唯一の方法は、ミューテーションを送信することであるためです。
vuex では、各ミューテーションには文字列イベント タイプ (ミューテーション タイプ) とコールバック関数 (ハンドラー) があります。
このコールバック関数は 2 つのパラメーターを受け入れることができ、最初のパラメーターは状態、2 番目のパラメーターは突然変異のペイロードです。
//... mutations: { /** * @method:只传入state,修改loading状态 * @param {bool} isLoading:loading状态 */ changeLoading(state) { state.isLoading = !state.isLoading } } store.commit('changeLoading') mutations: { /** * @method:传入state和payload,修改loading状态 * @param {bool} isLoading:loading状态 */ changeLoading(state,payload) { state.isLoading = payload.isLoading } } store.commit('changeLoading',{isLoading: true})
ミューテーションを送信するもう 1 つの方法は、type 属性を含むオブジェクトを直接使用することですが、上記の方法で処理した方がコードが読みやすくなるため、この方法はあまりお勧めしません。
store.commit({ type: 'changeLoading', isLoading: true })
4.mutation-types.js
複数人のコラボレーションが必要なプロジェクトでは、ミューテーション イベント タイプの代わりに定数を使用できます。これは、さまざまな Flux 実装で非常に一般的なパターンです。また、これらの定数を別のファイルに保存すると、共同開発が明確になります。
// mutation-types.js export const CHANGE_LOADING= 'CHANGE_LOADING' // mutation.js import { CHANGE_LOADING} from './mutation-types' export default{ [CHANGE_LOADING](state,payload){ state.isLoading = payload.isLoading }, }
mutation-typeでのイベントの種類の定義は、大まかに自分で定義した以下の仕様に従ってます
1. ミューテーションはイベントに似ているので、動詞で始まります
2 単語はアンダースコアで結ばれます
。3 、vuex に保存された状態は RECORD でマークされます
4. ローカルにキャッシュされた状態は SAVE でマークされます
もちろん、突然変異を通じて突然変異の意図を知ることができる限り、この仕様を自分で定義することもできます。タイプ、良好です。
5. Getter (getter.js)
たとえば、上で述べたように、非同期リクエスト中にマスク レイヤーを使用して読み込みを表示する必要がある場合があります。私の読み込みでは、状態に基づいて読み込みステータスを表示する必要があります。ゲッターを使用せずに、計算されたプロパティを使用して処理することを選択します。
computed: { loadingTxt () { return this.$store.state.isLoading ? '加载中' : '已完成'; } }
ただし、読み込みは多くのコンポーネントで使用する必要があります。次に、関数をコピーするか、共有関数に抽出して複数の場所にインポートする必要がありますが、どちらの方法も理想的ではありません。
Getterを使えば全てが美しくなります。
//getter.js export default { loadingTxt:(state) =>{ return state.isLoading ? '加载中' : '已完成'; } };
計算されたプロパティと同様に、ゲッターの戻り値は依存関係に従ってキャッシュされ、依存関係の値が変更された場合にのみ再計算されます。
そして、Getter は 2 番目のパラメーターとして他のゲッターを受け入れることもできます:
export default { loadingTxt:(state) =>{ return state.isLoading ? '加载中' : '已完成'; }, isLoading:(state,getters) => { return 'string' === typeof getters.loadingTxt ? true : false; } };
ストア内のゲッターは、mapGetter 補助関数を通じてローカルに計算されたプロパティにマップできます
//组件中 import { mapGetters } from 'vuex' export default { data(){ return { //... } }, computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters([ 'loadingTxt', 'isLoading', // ... ]) } }
6.Action (action.js)
関数アクション ミューテーションと同様に、どちらもストア内の状態を変更しますが、アクションとミューテーションには 2 つの違いがあります:
1. アクションは主に非同期操作を処理しますが、アクションはそのような制限を受けません。つまり、アクションでは同期操作と非同期操作の両方を処理できます
2. アクションは状態を変更し、最後にミューテーションを送信します
商品を追加するときは、ショッピング カートを例に挙げます。最初にバックエンドと通信する必要があります。これには SKU が関係するか、ユーザーが SKU を追加しただけで注文しなかった場合に発生します。
バックグラウンドの追加が成功すると、フロントエンドは新しく追加された製品を表示します。失敗した場合は、追加が失敗したことをユーザーに伝える必要があります。
const actions = { checkout ({ state, commit, //rootState }, products) { const savedCartItems = [...state.added] commit(SET_CHECKOUT_STATUS, null) // 置空购物车 commit(SET_CART_ITEMS, { items: [] }) shop.buyProducts( products, //成功 () => commit(SET_CHECKOUT_STATUS, 'successful'), //失败 () => { commit(SET_CHECKOUT_STATUS, 'failed') commit(SET_CART_ITEMS, { items: savedCartItems }) } ) } }
7.module
当我们的项目足够大的时候,单一的状态树这个时候就会显得很臃肿了。因为需要用vuex进行状态管理的状态全部集中在一个state对象里面。
所以,当一个东西大了以后,我们就要想办法进行分割,同样的道理,我们熟知的分冶法和分布式其实也是基于这样的一个思想在里面。而vuex提供了module,我们就可以去横向的分割我们的store。
比如说,我在项目中需要去做一个购物车这样的东西,这在电商的项目中也是常见的需求。
//shopCart.js import shop from '../../api/shop' import { ADD_TO_CART, SET_CART_ITEMS, SET_CHECKOUT_STATUS } from '../mutation-types' const state = { added: [], checkoutStatus: null } /** * module getters * @param {Object} state:模块局部state * @param {Object} getters:模块局部getters,会暴露到全局 * @param {Object} rootState:全局(根)state */ const getters = { checkoutStatus: state => state.checkoutStatus, cartProducts: (state, getters, rootState) => { return state.added.map(({ id, quantity }) => { const product = rootState.products.all.find(product => product.id === id) return { title: product.title, price: product.price, quantity } }) }, cartTotalPrice: (state, getters) => { return getters.cartProducts.reduce((total, product) => { return total + product.price * product.quantity }, 0) } } /** * module actions * @param {Object} state:模块局部state * @param {Object} getters:模块局部getters,会暴露到全局 * @param {Object} rootState:全局(根)state */ const actions = { checkout ({ state, commit, //rootState }, products) { const savedCartItems = [...state.added] commit(SET_CHECKOUT_STATUS, null) // 置空购物车 commit(SET_CART_ITEMS, { items: [] }) shop.buyProducts( products, //成功 () => commit(SET_CHECKOUT_STATUS, 'successful'), //失败 () => { commit(SET_CHECKOUT_STATUS, 'failed') commit(SET_CART_ITEMS, { items: savedCartItems }) } ) } } /** * module mutations * @param {Object} state:模块局部state * @param payload:mutation的载荷 */ const mutations = { //用id去查找商品是否已存在, [ADD_TO_CART] (state, { id }) { state.checkoutStatus = null const record = state.added.find(product => product.id === id) if (!record) { state.added.push({ id, quantity: 1 }) } else { record.quantity++ } }, [SET_CART_ITEMS] (state, { items }) { state.added = items }, [SET_CHECKOUT_STATUS] (state, status) { state.checkoutStatus = status } } export default { state, getters, actions, mutations }
在module的定义的局部state,getters,mutation,action中,后三个都会暴露到全局的store中去,这样使得多个模块能够对同一 mutation 或 action 作出响应。就不需要在其他的模块中去定义相同的mutation或action了。
而这里的state是局部的。这也导致后来的持久化无法去处理用module分割后的state。
如同上面的module =》shopCart,
当我们无论是在index.js里面或者其他的module中,shopCart里面的getters或者action或者mutations,我们都可以去使用。
//test.js const state = { isTest:false }; const getters = { isTest :state => state.isTest, checkTestStatus:(state,getters) => { return getters.checkoutStatus; } }; export default { state, getters, } //组件中 ...mapGetters([ 'checkTestStatus' ]) //... created(){ this.checkTestStatus ;//null }
如果说,我就想让我的module里面的定义的全部都是独享的。我们可以使用module的命名空间,通过设置namespaced: true。
//test.js const getters = { // 在这个模块的 getter 中,`getters` 被局部化了 // 你可以使用 getter 的第四个参数来调用 `rootGetters` someGetter (state, getters, rootState, rootGetters) { getters.someOtherGetter // 'test/someOtherGetter' rootGetters.someOtherGetter // 'someOtherGetter' }, someOtherGetter: state => { ... } }; const actions = { // 在这个模块中, dispatch 和 commit 也被局部化了 // 他们可以接受 `root` 属性以访问根 dispatch 或 commit someAction ({ dispatch, commit, getters, rootGetters }) { getters.someGetter // 'test/someGetter' rootGetters.someGetter // 'someGetter' dispatch('someOtherAction') // 'test/someOtherAction' dispatch('someOtherAction', null, { root: true }) // 'someOtherAction' commit('someMutation') // 'test/someMutation' commit('someMutation', null, { root: true }) // 'someMutation' }, someOtherAction ({ state,commit }, payload) { ... } } export default { namespaced: true, state, getters, actions, mutations }
8.持久化state的工具:vuex-persistedstate
用过vuex的肯定会有这样一个痛点,就是刷新以后vuex里面存储的state就会被浏览器释放掉,因为我们的state都是存储在内存中的。
而像登录状态这样的东西,你不可能一刷新就让用户重新去登录吧!所以,我们会去选择把状态存储到本地。
这样一来问题貌似是解决了,但是当我们需要使用的时候,我们就需要不断的从本地,通过getStore这样的方法去取得我们state。如果需要更新的话,我们又要在mutation里面通过setStore这样的方法去处理它。
虽然,我们的setStore都是在操作了state以后再去调用的,也就是说无论是通过vuex的logger或者vue的dev tool我们都是可以对local里面的状态进行跟踪的,但是,我们无法保证我们每次都记着去写setStore。
这样一来,在共享state的组件中,我们的代码可能就会是这样的。
import { getStore } from '@/util' //组件中 mounted(){ this.foo = getStore('foo'); this.bar = getStore('bar'); //.... }
那么,如何去改进呢?
我们能想到的就是,能不能让state不是保存在内存中,而是存储在本地。
而vuex-persistedstate做了这样的事情,它帮我们将store里面的state映射到了本地环境中。这样一来,我通过提交mutation改变的state,会动态的去更新local里面对应的值。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
在vue 2.x 中使用axios如何封装的get 和post方法
使用node应用中timing-attack存在哪些安全漏洞
以上がvuex と永続性の使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Vue2.x は現在最も人気のあるフロントエンド フレームワークの 1 つであり、グローバル状態を管理するためのソリューションとして Vuex を提供します。 Vuex を使用すると、状態管理がより明確になり、保守が容易になります。開発者が Vuex をより適切に使用し、コードの品質を向上させるために、Vuex のベスト プラクティスを以下に紹介します。 1. モジュラー組織状態の使用 Vuex は単一の状態ツリーを使用してアプリケーションのすべての状態を管理し、コンポーネントから状態を抽出することで、状態管理をより明確かつ理解しやすくします。多くの状態を持つアプリケーションではモジュールを使用する必要があります

Vuexは何をするのですか? Vue 公式: 状態管理ツール 状態管理とは? 複数のコンポーネント間で共有する必要があり、1 つの変更ですべてが変更される、応答性の高い状態。たとえば、グローバルに使用されるステータス情報: ユーザーのログイン ステータス、ユーザー名、地理的位置情報、ショッピング カート内の商品など。現時点では、グローバル ステータス管理のためのこのようなツールが必要であり、Vuex はそのようなツールです。単一ページの状態管理 ビュー –> アクション –> 状態 ビュー レイヤ (ビュー) は、アクション (アクション) をトリガーして状態 (state) を変更し、ビュー レイヤ (ビュー) vuex (Vue3.
![Vue アプリケーションで vuex を使用するときに「エラー: [vuex] 変更ハンドラーの外で vuex ストアの状態を変更しません。」という問題を解決するにはどうすればよいですか?](https://img.php.cn/upload/article/000/000/164/168760467048976.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
Vue アプリケーションでは、vuex の使用が一般的な状態管理方法です。ただし、vuex を使用すると、「Error:[vuex]donotmutatevuexstorestateoutsidemutationhandlers」というエラー メッセージが表示されることがあります。このエラー メッセージは何を意味しますか?このエラー メッセージが表示されるのはなぜですか?このエラーを修正するにはどうすればよいですか?この記事では、この問題について詳しく説明します。エラーメッセージには次の内容が含まれます

面接でvuexの実装原理について聞かれたらどう答えるべきでしょうか? vuex の実装原理については以下の記事で詳しく解説していますので、お役に立てれば幸いです。
![Vue アプリケーションで vuex を使用するときに「エラー: [vuex] 不明なアクション タイプ: xxx」という問題を解決するにはどうすればよいですか?](https://img.php.cn/upload/article/000/887/227/168766615217161.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
Vue.js プロジェクトでは、vuex は非常に便利な状態管理ツールです。これは、複数のコンポーネント間で状態を共有するのに役立ち、状態の変更を管理する信頼性の高い方法を提供します。ただし、vuex を使用すると、「エラー:[vuex]unknownactiontype:xxx」というエラーが発生することがあります。この記事では、このエラーの原因と解決策について説明します。 1. エラーの原因 vuex を使用する場合、いくつかのアクションと mu を定義する必要があります。

Vue アプリケーションで Vuex を使用することは、非常に一般的な操作です。ただし、Vuex を使用しているときに、「TypeError: Cannotreadproperty'xxx'ofunknown」というエラー メッセージが表示されることがあります。このエラー メッセージは、未定義のプロパティ "xxx" を読み取れず、プログラム エラーが発生することを意味します。この問題の理由は実は非常に明白で、Vuex の特定の属性を呼び出すときに、この属性が正しく設定されていないことが原因です。

具体的な手順: 1. vuex (vue3 は 4.0 以降を推奨) pnpmivuex-S2 をインストールし、main.js で importstorefrom'@/store'//hx-app のグローバル構成を構成します constapp=createApp(App)app.use(store) 3新しい関連フォルダーとファイルを作成します。ここでは、異なる vuex 内に複数の js を構成します。vuex モジュールを使用して、異なるページとファイルを配置し、getters.jsindex.js コア ファイルを使用します。ここでは、代わりに Import.meta.glob が使用されます。の

Vue アプリケーションの開発プロセスでは、vuex を使用してアプリケーションの状態を管理することが非常に一般的です。ただし、vuex を使用する過程で、「エラー:'xxx'hasalreadybeendeclaredasadataproperty」というエラー メッセージが表示されることがあります。このエラー メッセージは不可解に思えますが、実際には Vue コンポーネントで値が繰り返し使用されていることが原因です。 . データ属性と vuex を定義する変数名
