1. Vuex是做什么的?
- 官方解釋: Vuex 是一個專為Vue.js 應用程式開發的 狀態管理模式
- 它采用 集中式存盤管理 應用的所有組件的狀態, 并以相應的規則保證狀態以一種可預測的方式發生變化
- Vuex 也繼承到Vue的官方除錯工具 devtools extension, 提供了諸如零配置的
time-travel除錯、狀態快斬訓入匯出等高級除錯功能,
- 狀態管理到底是什么?
- 狀態管理模式、集中式存盤管理
- 簡單的將其看成把需要多個組件共享的變數全部存盤在一個物件里面
- 然后, 將這個物件放在頂層的Vue實體中, 讓其他組件可以使用
- 那么,多個組件是不是就可以共享這個物件中的所有變數屬性了呢?
1.1 管理什么狀態?
- 有什么狀態是我們需要在多個組件間共享的呢?
- 如果做過大型開發, 一定遇到過多個狀態, 在多個界面間的共享問題
- 比如用戶的登錄狀態、用戶名稱、頭像、地理位置資訊等
- 比如商品的收藏、購物車中的物品等等
- 這些狀態資訊,我們都可以放在統一的地方, 對它進行保存和管理, 并且它們還是回應式的
1.2 單頁面的狀態管理
-
我們知道, 要在單個組件中進行狀態管理是一件非常簡單的事情
- 什么意思呢? 我們來看下面的圖片
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-GmJKAjRx-1630130671727)(img/image-20210609093647215.png)]](https://img-blog.csdnimg.cn/7ff1bf5026834e19befee7449b24133d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_14,color_FFFFFF,t_70,g_se,x_16)
-
這圖片中的三種東西, 怎么理解呢?
- State: 不用多說, 就是我們的狀態, 姑且可以當做就是data 中的屬性
- View: 視圖層, 可以針對State的變化, 顯示不同的資訊
- Actions: 這里的Actions 主要是用戶的各種操作: 點擊,輸入等等, 會導致狀態的改變
1.3 單頁面狀態管理的實作

- 在這個案例中, 我們有沒有狀態需要管理呢? , 沒錯,就是個數counter
- counter 需要某種方式被記錄下來, 也就是我們的 State
- counter 目前的值需要被顯示在界面中, 也就是我們的View部分
- 界面發生某些操作時 (我們這里是用戶的點擊, 也可以是用戶的input ), 需要去更新狀態, 也就是我們的 Actions
- 這就是一個基本的單頁面狀態管理
1.4 多頁面狀態管理
-
Vue 已經幫我們做好了單個界面的狀態管理, 但是如果是多個界面呢?
- 多個視圖都依賴同一個狀態 (一個狀態改了, 多個界面需要進行更新)
- 不同界面的 Actions 都想修改同一個狀態 (Home,vue需要修改, Profile.vue 也需要修改這個狀態)
-
也就是說對于某些狀態 (狀態1\狀態2\狀態3) 來說只屬于我們某一個視圖, 但是也有一些狀態( 狀態a\狀態b\狀態c ) 屬于多個視圖共同想要維護的
- 狀態1, 狀態2, 狀態3 你放在自己的房間中 ,你自己管理自己用, 沒問題
- 但是狀態a 狀態b 狀態c 我們希望交給一個大管家來統一幫助我們管理
- Vuex 就是為我們提供這個大管家的工具
-
全域單例模式 (大管家)
- 我們現在要做的就是將共享的狀態抽取出來, 交給我們的大管家, 統一進行管理
- 之后, 你們每個視圖, 按照我 規定好的 規定, 進行訪問和修改等操作
- 這就是 Vuex 背后的基本思想
1.5 Vuex 狀態管理圖例
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fSHGEakV-1630130671731)(img/image-20210609112315789.png)]](https://img-blog.csdnimg.cn/73e735c96b1f43e29dbafda93cb1e003.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
1.6 簡單的案例
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2AyjGRPr-1630130671733)(img/image-20210609113931957.png)]](https://img-blog.csdnimg.cn/4dc95bbc0e5848688a42321fc4e9cfc9.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
-
首先, 我們需要在某個地方存放我們的Vuex 代碼:
- 這里, 我們先創建一個檔案夾 store , 并且在其中創建一個 index.js檔案
- 在index.js檔案中寫入如下代碼
![* [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SVjZzS8j-1630130671734)(img/image-20210609114144869.png)]](https://img-blog.csdnimg.cn/259ecc6b85314d9c972af6e4e2f2eb4e.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_19,color_FFFFFF,t_70,g_se,x_16)
-
其次, 我們讓所有的Vue組件都可以使用這個
store物件-
來到
main.js檔案, 匯入store物件, 并且放在new Vue中 -
這樣, 在其他的Vue組件中, 我們就可以通過
$store的方式, 獲取到這個store物件了[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ifhPbJqh-1630130671735)(img/image-20210609114408524.png)]
-
-
使用Vuex 的 content
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ad44ZIOL-1630130671736)(img/image-20210609115136417.png)]](https://img-blog.csdnimg.cn/f127f7753ca4491692f6c72c0fd5c419.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
1.7 使用步驟
- 提取出一個公共的 store物件, 用于保存在多個組件中共享的狀態
- 將 store 物件放置在 new Vue 物件中, 這樣可以保證在所有的組件中都可以使用到
- 在其他組件中使用 store 物件中保存的狀態即可
- 通過
this.$store.state.屬性的方式來訪問狀態 - 通過
this.$store.commit( 'mutation中方法' )來修改狀態
- 通過
- 注意事項:
- 我們通過提交
mutation的方式, 而非直接改變store.state.count - 這是因為Vuex可以更明確的追蹤狀態的變化, 所以不要直接改變
store.state.count的值
- 我們通過提交
2. Vuex 核心概念
- Vuex有幾個比較核心的概念:
- State
- Getters
- Mutation
- Action
- Module
2.1 State 單一狀態樹
- Vuex提出使用單一狀態樹, 什么是單一狀態樹呢?
- 英文名稱是 Single Source of Truth, 也可以翻譯成單一資料源
- 但是, 它是什么呢? 我們來看一個生活中的例子
- OK, 我用一個生活中的例子做一個簡單的類比
- 我們知道, 在國內我們有很多的資訊需要被記錄, 比如上學時的個人檔案, 作業后的社保記錄, 公積金記錄,結婚后的婚姻資訊,以及其他相關的戶口, 醫療, 文憑, 房產記錄等等
- 這些資訊被分散在很多地方進行管理, 有一天你需要辦某個業務時, (比如入戶某個城市), 你會發現你需要到各個對應的作業地點去列印, 蓋章各種資料資訊, 最后到一個地方提交證明你的資訊五五
- 這種保存資訊的方案, 不僅僅低效, 而且不方便管理, 以及日后的維護也是一個龐大的工程(需要大量的各個部門的人力來維護)
- 這個和我們在應用開發中比較類似:
- 如果你的狀態資訊是保存到多個Store物件中的, 那么之后的管理和維護等等都會變得特別困難
- 所以Vuex 也使用了單一狀態樹來管理應用層級的全部狀態
- 單一狀態樹能夠讓我們最直接的方式找到某個狀態的片段, 而且在之后的維護和除錯程序中, 也可以非常方便的管理和維護
2.2 Getter 基本使用
-
有時候,我們需要從store中獲取一些state變異后的狀態,比如下面的Store中:
// 獲取 state 平方后的值 const store = new Vuex.Store({ state: { content: 1000 } } -
我們可以在 Store 中定義 getters
const store = new Vuex.Store({ state: { content: 1000 }, getters: { powerContent(state) { return state.content * state.content; } } }) -
在組件中呼叫
<template> <div id="app"> <h2>-----------app組件 getters 相關資訊-------------</h2> <p>content的平方{{ $store.getters.powerContent }}</p> </div> </template> <script> import HelloVuex from "./components/HelloVuex"; export default { name: 'App', components: { HelloVuex } } </script> <style> </style>
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-X8xElOnz-1630130671737)(img/image-20210609193249477.png)]](https://img.uj5u.com/2021/09/01/260156010734432.png)
2.2.1 Getters 作為引數和傳遞引數
-
如果我們已經有了一個獲取所有年齡大于20歲學生串列的 getter, 那么代碼可以這樣來寫

-
getters默認是不能傳遞引數的, 如果希望傳遞引數, 那么只能讓getter 本身回傳另一個函式
-
比如上面的案例中, 我們希望根據 age 獲取用戶資訊
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5dLuSe95-1630130671737)(img/image-20210610113326867.png)]](https://img.uj5u.com/2021/09/01/260156010734433.png)
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-d2dMxIgh-1630130671738)(img/image-20210610113312679.png)]](https://img-blog.csdnimg.cn/1d077be20809452b95e9937a77b56c16.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
-
2.3 Mutation 狀態更新
-
Vuex 的store 狀態的更新唯一方式: 提交Mutation
-
Mutation主要包括兩部分:
- 字串的 事件型別(type)
- 一個回呼函式(handler) ,該回呼函式的第一個引數就是 state
-
mutation 的定義方式:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4WB160Pu-1630130671739)(img/image-20210610113935427.png)]](https://img-blog.csdnimg.cn/325126c0a3c94f32990774095dd14b2a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_13,color_FFFFFF,t_70,g_se,x_16)
-
通過mutation更新狀態
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kWyLRswx-1630130671739)(img/image-20210610114006902.png)]](https://img-blog.csdnimg.cn/a3f867b6205147ea9bc4b487273b225a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
2.3.1 Mutation傳遞引數
-
在通過mutation 更新資料的時候, 有可能我們希望攜帶一些額外的引數
- 引數被稱為是 mutation 的載荷(Payload)
-
Mutation中的代碼:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ynHPgdW6-1630130671740)(img/image-20210610120032755.png)]](https://img.uj5u.com/2021/09/01/260156010734434.png)
-
組件中的代碼:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XJLsDv7a-1630130671740)(img/image-20210610120055847.png)]](https://img.uj5u.com/2021/09/01/260156010734435.png)
-
但是如果引數不是一個呢?
- 比如我們有很多引數需要傳遞
- 這個時候, 我們通常會以物件的形式傳遞, 也就是payload是一個物件
- 這個時候可以再從物件中取出相關的資訊
methods: { addCount(count){ this.$store.commit({ type:'increaseCount', count }) } }mutations: { increaseCount(state, payload) { console.log(payload); state.content += payload.count; } }![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Sva0Kiy7-1630130671740)(img/image-20210610121223962.png)]](https://img.uj5u.com/2021/09/01/260156010734436.png)
2.3.2 Mutation 回應規則
-
Vuex 的store 中的state是回應式的, 當state中的資料發生改變時, Vue組件會自動更新
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bzlo1b3S-1630130671741)(img/屬性被添加到回應式系統中.jpg)]
-
這就要求我們必須遵守一些Vuex對應的規則:
- 提前在store中初始化好所需的屬性
- 當給 state中的物件添加新屬性時, 使用下面的方式:
- 方式一: 使用
Vue.set(obj,'newProp',123); - 方式二: 用新物件給舊物件重新賦值
- 方式一: 使用
- 當要洗掉 state中的屬性時, 使用 Vue.delete
Vue.delete(state,'key')
![* [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qdJkJ0Sr-1630130671741)(img/image-20210615105432004.png)]](https://img-blog.csdnimg.cn/b24c6a03b64146f0b177b8a1e7e7120c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-r34lkPry-1630130671742)(img/image-20210615105443464.png)]](https://img-blog.csdnimg.cn/b5c44a81397b4164a7766c893e6a8bc6.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
2.3.3 Mutation 常量型別 - 概念
- 我們來考慮下面的問題:
- 在mutation中, 我們定義了很多事件型別(也就是其中的方法名稱)
- 當我們的專案增大時, Vuex管理的狀態越來越多, 需要更新狀態的情況越來越多, 那么意味著Mutation 中的方法越來越多
- 方法過多, 使用者需要花費大量的精力去記住這些方法, 甚至是多個檔案間來回切換, 查看方法名稱, 甚至如果不是復制的時候, 可能還會出現寫錯的情況
- 如何避免上述的問題呢?
- 在各種 Flux 視線中, 一種很常見的方案就是使用常量 替代 Mutation 事件的型別
- 我們可以將這些常量放在一個單獨的檔案中, 方便管理以及讓整個app所有的事件型別一目了然
- 具體怎么做呢?
- 我們可以創建一個檔案: mutation-types.js , 并且在其中定義我們的常量
- 定義常量時, 我們可以使用ES2015中的風格, 使用一個常量來作為函式的名稱
2.3.4 Mutation 常量型別 - 代碼



2.3.5 Mutation 同步函式
-
通常情況下, Vuex 要求我們 Mutation中的方法必須是同步方法
- 主要的原因是當我們使用devtools除錯工具時, devtools 可以幫助我們捕捉 mutation的快照
- 但是如果是異步操作, 那么devtools將不能很好的追蹤這個操作什么時候會被完成
-
比如我們之前的代碼, 當執行更新時, devtools 中會有如下資訊


-
但是, 如果Vuex中的代碼使用了異步函式


-
你會發現state中的info資料一直沒有被改變, 因為它無法追蹤到
2.4 Action 的基本定義
-
我們強調, 不要在Mutation中進行異步操作
- 但是某些情況, 我們確實希望在Vuex 中進行一些異步操作, 比如網路請求, 必然是異步的, 這個時候怎么處理呢?
- Action 類似于Mutation, 但是是用來代替Mutation進行異步操作的
-
Action的基本使用代碼如下:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fel1wxKd-1630130671742)(img/image-20210615145518468.png)]](https://img-blog.csdnimg.cn/02dfcf5f9d1b4fcd97b46a2d9b98742b.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
-
context 是什么?
- context 是和store 物件具有相同方法和屬性的物件
- 也就是說, 我們可以通過context 去進行commit 相關的操作, 也可以獲取 context, state等
- 但是注意, 這里它們并不是同一個物件, 為什么呢? 我們后面學習Modules的時候,再具體說
-
這樣的代碼是否多此一舉呢?
- 我們定義了actions, 然后又在actions中去進行commit, 這不是脫褲放屁嗎?
- 事實上并不是這樣, 如果在Vuex 中有異步操作, 那么我們可以在actions 中完成了
2.4.1 Action 的分發
-
在Vue組件中, 如果我們呼叫action中的方法, 那么就需要使用dispatch
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳
![(img-VWWHXM0l-1630130671743)(img/image-20210615152539535.png)]](https://img.uj5u.com/2021/09/01/260156010734438.png)
-
同樣的, 也是支持傳遞payload
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rQWVOub9-1630130671745)(img/image-20210615152553344.png)]](https://img-blog.csdnimg.cn/8da8be7db4084cac8786da948aff7dee.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_18,color_FFFFFF,t_70,g_se,x_16)
2.4.2 Action 回傳的 Promise
-
前面我們學習ES6語法的時候說過, Promise經常用于異步操作
- 在Action中, 我們可以將異步操作放在一個Promise中, 并且在成功或者失敗后, 呼叫對應的resolve或reject
-
ok , 我們來看下面的代碼:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YIwrMjjn-1630130671746)(img/image-20210615152818172.png)]](https://img-blog.csdnimg.cn/cdc0582f11e247cfb24f0fac3bd2f986.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)

2.5 認識Modules
-
Modules 是模塊的意思, 為什么在Vuex 中我們要使用模塊呢?
- Vue使用單一狀態樹, 那么也意味著很多狀態都會交給Vuex來管理
- 當應用變得非常復雜時, store物件就有可能變的相當臃腫
- 為了解決這個問題, Vuex 允許我們將store分割成模塊(Module), 而每個模塊擁有自己的 state、mutations、actions、getters等
-
我們按照什么樣的方式來組織模塊呢?

2.5.1 Module 區域狀態
- 上面的代碼中, 我們已經有了整體的組織結構, 下面我們來看看具體的區域模塊中的代碼如何書寫
- 我們在moduleA中添加state、mutations、getters
- mutation 和 getters 接收的第一個引數是區域狀態物件
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9bFej7Ue-1630130671747)(img/image-20210615163913336.png)]](https://img-blog.csdnimg.cn/12e13b36cc2546d19dd2529808fd9a0c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_15,color_FFFFFF,t_70,g_se,x_16)
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-M4AH1tOi-1630130671747)(img/image-20210615163904913.png)]](https://img-blog.csdnimg.cn/68d167c623214e9690f4e18057aadd26.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
- 注意:
- 雖然, 我們的 doubleCount 和 increment 都是定義在物件內部的
- 但是在呼叫的時候, 依然是通過
this.$store來呼叫的
專案結構
- 當我們的Vuex 幫助我們管理過多的內容時, 好的專案結構可以讓我們的代碼更加清晰

2.5.1 Module 區域狀態
-
上面的代碼中, 我們已經有了整體的組織結構, 下面我們來看看具體的區域模塊中的代碼如何書寫
- 我們在moduleA中添加state、mutations、getters
- mutation 和 getters 接收的第一個引數是區域狀態物件


-
注意:
- 雖然, 我們的 doubleCount 和 increment 都是定義在物件內部的
- 但是在呼叫的時候, 依然是通過
this.$store來呼叫的
專案結構
-
當我們的Vuex 幫助我們管理過多的內容時, 好的專案結構可以讓我們的代碼更加清晰
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sMczg1G8-1630130671747)(img/image-20210615165524047.png)]](https://img-blog.csdnimg.cn/ac4ab35254184713b7597a0f9368c2bc.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6b6Z54yr5LiN54Ot,size_20,color_FFFFFF,t_70,g_se,x_16)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/296383.html
標籤:其他
上一篇:js原生搜索框自動搜索
