配置 vuex 和 vuex 本地持久化
目錄
vuex是什么
-
vuex 的五個(gè)核心概念
- State 定義狀態(tài)(變量)
- Getter 獲取狀態(tài)(變量的值)
- Mutation 修改狀態(tài)(修改變量的值)
- Action 觸發(fā) mutation 函數(shù),從而修改狀態(tài)
- Module 當(dāng)狀態(tài)很多時(shí),把狀態(tài)分開來管理
通過vuex進(jìn)行跨組件通信
vuex 本地持久化
(一) vuex是什么
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。
- 狀態(tài): 本質(zhì)上就是一個(gè)變量,賦予不同的值就是不同的狀態(tài),管理狀態(tài)實(shí)際上就是管理一堆變量
- 響應(yīng)式,vuex跟全局變量不同,修改了vuex的某個(gè)狀態(tài),依賴這個(gè)狀態(tài)的視圖都會(huì)發(fā)生改變
(二) vuex的5個(gè)核心概念
1. State 定義狀態(tài)(變量), 輔助函數(shù)mapState
2. Getter 獲取狀態(tài)(變量的值),同時(shí)可以對狀態(tài)進(jìn)行處理, 輔助函數(shù)mapGetters
3. Mutation 修改狀態(tài)(修改變量的值)
4. Action 觸發(fā) mutation 函數(shù),從而修改狀態(tài),支持異步
5. Module 當(dāng)狀態(tài)很多時(shí),把狀態(tài)分開來管理
(三) 配置vuex
-
安裝vuex
npm i vuex
-
vuex配置
在根目錄新建/store/index.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); const config = { // 定義狀態(tài) state: { isLogin: false }, // getters getters: { // isLogin:(state) =>{ // return state.isLogin; // }, // 等同上面的寫法 isLogin: state => state.isLogin }, // 修改state里面的變量 mutations: { // state指向上面的state,payload是調(diào)用muation時(shí)傳過來的參數(shù) updateLogin(state, payload) { state.isLogin = payload; } }, // action行為 actions: { }, // module modules: { } } export default new Vuex.Store(config);
-
在main.js導(dǎo)入并掛載到vue的實(shí)例上
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定義的狀態(tài)
-
通過this.$store.state.xxx 來取,具體使用
created() { console.log(this.$store.state.isLogin); console.log(this.$store.state.firstName); } // 通常我們會(huì)定義計(jì)算屬性來取值,比如 computed: { // 自定義計(jì)算屬性 isLogin() { // 獲取vuex的isLogin的值 return this.$store.state.isLogin } }
-
通過輔助函數(shù)mapState來獲取
import {mapState} from 'vuex' data() { return { addr: '廣西' }; }, computed: mapState({ // 取state里count的值 count: 'count', // 取state里count的值,用countAlias變量接收 countAlias: 'count', // 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù) fullName(state) { return this.addr + state.firstName + state.lastName; } }) // 如果需要定義其它的計(jì)算屬性,就按照下面的寫法 computed: { // 其他的計(jì)算屬性 total() { return 500 }, ...mapState({ // 取state里count的值 count: 'count', // 取state里count的值,用countAlias變量接收 countAlias: 'count', // 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù) fullName(state) { return this.addr + state.firstName + state.lastName; } }) }
-
通過getters和mapGetters來取
// 定義一個(gè)用來獲取fullName的getter getters: { fullName(state) { return state.firstName + state.lastName; } }, // 通過mapGetters import {mapGetters} from 'vuex'; computed: { fullName() { return this.$store.getters.fullName; } }
使用getters的好處是,當(dāng)我們在vuex中的index.js的文件中定義好了getters的方法,我們可以在任意的組件中使用getters的方法,非常的方便。例如我們有一個(gè)組件a.vue,需要使用到getters的方法,我們直接在該組件的計(jì)算屬性computed中使用即可:
computed: { fullName() { return this.$store.getters.fullName; } }
(五) 修改state中的狀態(tài)
-
定義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: { /** * 定義一個(gè)修改name的mutation * state是上面的定義的state * payload是新的數(shù)據(jù) */ updateName(state, payload) { state.name = payload; } } })
在需要的時(shí)候調(diào)用mutation進(jìn)行修改state里的name狀態(tài)
```
// 第一個(gè)參數(shù)是mutation的名字,第二參數(shù)是要修改成的數(shù)據(jù)
this.$store.commit('updateName','老胡');
```
(六) 綜合例子: 通過vuex實(shí)現(xiàn)加減
-
在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; } } } })
-
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 本地持久化
當(dāng)刷新頁面,項(xiàng)目重新加載,vuex 會(huì)重置,所有狀態(tài)回到初始狀態(tài),使用 vuex-persistedstate 可以避免這種情況
-
安裝 vuex-persistedstate
npm i vuex-persistedstate
-
在vuex中,添加plugins
import createPersistedState from 'vuex-persistedstate' plugins: [createPersistedState()],
// 具體例子如下
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate'
// 導(dǎo)入模塊
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的使用
就是為了分塊管理,當(dāng)我們的狀態(tài)太多的時(shí)候,全寫在vuex中不易于管理,我們需要在外面的文件寫好后,然后再倒進(jìn)來,就像我們的后端接口model一樣,都是為了方便管理
-
配置模塊的vuex
export default { state: { cartNum: 10 }, getters: { }, mutations: { updateCartNum(state, payload) { state.cartNum = payload; } }, actions: { } }
-
獲取狀態(tài)
<template> <div>{{cartNum}}</div> </template> <script> import { mapState } from "vuex"; export default { computed: mapState({ cartNum(state) { return state.cart.cartNum; } }) }; </script>
在vuex的index.js中導(dǎo)入模塊
-
修改狀態(tài)
this.$store.commit("updateCartNum", 200);
(八) action
Action 類似于 mutation,都是用來修改vuex的狀態(tài), 不同在于:
- Action 提交的是 mutation,而不是直接變更狀態(tài)。
- Action 可以包含任意異步操作。
-
配置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 可以拿到一個(gè)類似store的實(shí)例 * @param {*} payload 修改的數(shù)據(jù) */ updateNum(ctx, payload) { setTimeout(() => { ctx.commit('updateNum', payload); }, 3000) } } })
-
派發(fā)action,在需要的地方,調(diào)用以下方法
this.$store.dispatch("updateNum", 500);