vuex的使用

配置 vuex 和 vuex 本地持久化

目錄

  1. vuex是什么

  2. vuex 的五個核心概念

    • State 定義狀態(變量)
    • Getter 獲取狀態(變量的值)
    • Mutation 修改狀態(修改變量的值)
    • Action 觸發 mutation 函數,從而修改狀態
    • Module 當狀態很多時,把狀態分開來管理
  3. 通過vuex進行跨組件通信

  4. vuex 本地持久化

(一) vuex是什么

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。

  1. 狀態: 本質上就是一個變量,賦予不同的值就是不同的狀態,管理狀態實際上就是管理一堆變量
  2. 響應式,vuex跟全局變量不同,修改了vuex的某個狀態,依賴這個狀態的視圖都會發生改變

(二) vuex的5個核心概念

1. State 定義狀態(變量), 輔助函數mapState
2. Getter 獲取狀態(變量的值),同時可以對狀態進行處理, 輔助函數mapGetters
3. Mutation 修改狀態(修改變量的值)
4. Action 觸發 mutation 函數,從而修改狀態,支持異步
5. Module 當狀態很多時,把狀態分開來管理

(三) 配置vuex

  1. 安裝vuex
    npm i vuex
    
  1. vuex配置

    在根目錄新建/store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    const config = {
        // 定義狀態
        state: {
            isLogin: false
        },
    
        // getters
        getters: {
            // isLogin:(state) =>{
            //     return state.isLogin;
            // },
            // 等同上面的寫法
            isLogin: state => state.isLogin
        },
    
        // 修改state里面的變量
        mutations: {
            // state指向上面的state,payload是調用muation時傳過來的參數
            updateLogin(state, payload) {
                state.isLogin = payload;
            }
        },
    
        // action行為
        actions: {
    
        },
    
        // module
        modules: {
    
        }
    }
    export default new Vuex.Store(config);
    
  2. 在main.js導入并掛載到vue的實例上
    import Vue from 'vue'
    import App from './App.vue'
    import store from './store/index'
    
    Vue.config.productionTip = false
    
    new Vue({
      store,
      render: h => h(App),
    }).$mount('#app')
    

(四) 獲取在vuex定義的狀態

  1. 通過this.$store.state.xxx 來取,具體使用
    created() {
        console.log(this.$store.state.isLogin);
        console.log(this.$store.state.firstName);
    }
    
    // 通常我們會定義計算屬性來取值,比如
    computed: {
        // 自定義計算屬性
        isLogin() {
          // 獲取vuex的isLogin的值
          return this.$store.state.isLogin
        }
    }
    
  2. 通過輔助函數mapState來獲取
      import {mapState} from 'vuex'
      
      data() {
        return {
          addr: '廣西'
        };
      },
     
     computed: mapState({
        // 取state里count的值
        count: 'count',
     // 取state里count的值,用countAlias變量接收
        countAlias: 'count',
        // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數
        fullName(state) {
          return this.addr + state.firstName + state.lastName;
        }
      })
      
     // 如果需要定義其它的計算屬性,就按照下面的寫法
     computed: {
         // 其他的計算屬性
         total() {
             return 500
         },
         ...mapState({
               // 取state里count的值
                count: 'count',
                // 取state里count的值,用countAlias變量接收
                countAlias: 'count',
                // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數
                fullName(state) {
                  return this.addr + state.firstName + state.lastName;
                }
          })
     }
    
  3. 通過getters和mapGetters來取
    // 定義一個用來獲取fullName的getter
      getters: {
            fullName(state) {
                return state.firstName + state.lastName;
            }
        },
    
    // 通過mapGetters
    import {mapGetters} from 'vuex';
    
    computed: {
         fullName() {
             return this.$store.getters.fullName;
         }
    }
    

    使用getters的好處是,當我們在vuex中的index.js的文件中定義好了getters的方法,我們可以在任意的組件中使用getters的方法,非常的方便。例如我們有一個組件a.vue,需要使用到getters的方法,我們直接在該組件的計算屬性computed中使用即可:

    computed: {
         fullName() {
             return this.$store.getters.fullName;
         }
    }
    

(五) 修改state中的狀態

  1. 定義state和mutation

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        state: {
            name: "沒名字",
            count: 1
        },
        getters: {
    
        },
        // 修改state里的值必須通過mutation來修改
        mutations: {
            /**
             * 定義一個修改name的mutation
             * state是上面的定義的state
             * payload是新的數據
             */
            updateName(state, payload) {
                state.name = payload;
            }
        }
    })
    
  2. 在需要的時候調用mutation進行修改state里的name狀態

```
// 第一個參數是mutation的名字,第二參數是要修改成的數據
this.$store.commit('updateName','老胡');
```

(六) 綜合例子: 通過vuex實現加減

  1. 在vuex里配置state和mutation

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        state: {
            count: 0
        },
    
        mutations: {
            addOne(state, payload) {
                state.count = state.count + 1;
            },
            minusOne(state, payload) {
                if (state.count > 0) {
                    state.count = state.count - 1;
                }
            }
        }
    })
    
  2. index.vue的配置

    <template>
      <div>
        <button @click="minus">-</button>
        <span>{{count}}</span>
        <button @click="add">+</button>
      </div>
    </template>
    
    <script>
    import { mapState } from "vuex";
    export default {
      computed: mapState({
        count: "count"
      }),
    
      methods: {
        add() {
          this.$store.commit("addOne");
        },
        minus() {
          this.$store.commit("minusOne");
        }
      }
    };
    </script>
    

(六) vuex 本地持久化

當刷新頁面,項目重新加載,vuex 會重置,所有狀態回到初始狀態,使用 vuex-persistedstate 可以避免這種情況

  1. 安裝 vuex-persistedstate

    npm i vuex-persistedstate
    
  2. 在vuex中,添加plugins

     import createPersistedState from 'vuex-persistedstate'
     
     plugins: [createPersistedState()],
    

    // 具體例子如下

import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate'
// 導入模塊
import login from './module/login'
import my from './module/my'
Vue.use(Vuex);
export default new Vuex({
    plugins: [createPersistedState()],
    // 模塊
    modules: {
      login,
      my
    },
    state: {
        isLogin: false,
        username: '',
        token: ''
    },
    getters: {
        isLogin: state => state.isLogin,
        token: state => state.token,
        username: state => state.username
    },
    mutations: {
        updateLogin(state, payload) {
            state.isLogin = payload;
        },
        updateToken(state, payload) {
            state.token = payload;
        },
        updateUsername(state, payload) {
            state.username = payload;
        }
    },
    actions: {
      LoginAction({commit}, payload) {
        commit('updateLogin',payload)
      },
      TokenAction({commit}, payload) {
        commit('updateToken',payload)
      },
      UsernameAction({commit}, payload) {
        commit('updateUsername',payload)
      },
    }
})

(七) modules的使用

就是為了分塊管理,當我們的狀態太多的時候,全寫在vuex中不易于管理,我們需要在外面的文件寫好后,然后再倒進來,就像我們的后端接口model一樣,都是為了方便管理

  1. 配置模塊的vuex

    export default {
        state: {
            cartNum: 10
        },
    
        getters: {
    
        },
    
        mutations: {
            updateCartNum(state, payload) {
                state.cartNum = payload;
            }
        },
    
        actions: {
    
        }
    }
    
  2. 獲取狀態

    <template>
      <div>{{cartNum}}</div>
    </template>
    
    <script>
    import { mapState } from "vuex";
    export default {
      computed: mapState({
        cartNum(state) {
          return state.cart.cartNum;
        }
      })
    };
    </script>
    

在vuex的index.js中導入模塊


image.png
  1. 修改狀態

     this.$store.commit("updateCartNum", 200);
    

(八) action

Action 類似于 mutation,都是用來修改vuex的狀態, 不同在于:

  • Action 提交的是 mutation,而不是直接變更狀態。
  • Action 可以包含任意異步操作。
  1. 配置action

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        state: {
            num: 10
        },
    
        mutations: {
            updateNum(state, payload) {
                state.num = payload;
            }
        },
    
        actions: {
            /**
             * 修改num的action
             * @param {*} ctx 可以拿到一個類似store的實例
             * @param {*} payload 修改的數據
             */
            updateNum(ctx, payload) {
                setTimeout(() => {
                    ctx.commit('updateNum', payload);
                }, 3000)
            }
        }
    })
    
  2. 派發action,在需要的地方,調用以下方法

     this.$store.dispatch("updateNum", 500);
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 目錄 vuex是什么 vuex 的五個核心概念State 定義狀態(變量)Getter 獲取狀態(變量的值)Mut...
    北冥有魚_425c閱讀 757評論 0 5
  • ### store 1. Vue 組件中獲得 Vuex 狀態 ```js //方式一 全局引入單例類 // 創建一...
    蕓豆_6a86閱讀 352評論 0 0
  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統中,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 2,962評論 0 7
  • 從別處搬的代碼用久了,一直不知道Vuex具體是為了干什么的,該怎么去用它。 Vuex是什么vuex的核心是一個st...
    格子GiMi閱讀 314評論 0 0
  • 瑋蓮 在這個自然繁華的春天里 在這個人們吵著盡享花開的春天里 春風吹來你的名字—— 海子 讀著《面朝大海,春暖花開...
    驕陽下的一朵蓮閱讀 530評論 7 14