vuex? vue 專用 狀態(tài)管理模式? 采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生改變。
1,狀態(tài) :本質(zhì)上就是一個變量,賦予不同的值就是不同的狀態(tài),管理狀態(tài)實(shí)際上就是管理一堆變量。
2,響應(yīng)式 ,vuex 跟全局變量不同,修改了vuex 的某個狀態(tài),依賴這個狀態(tài)的試圖都會發(fā)生改變。
(二)vuex 的五個核心概念
1,state? 定義狀態(tài)(變量),輔導(dǎo)函數(shù)mapState
2, Getter 獲取狀態(tài)(變量的值),同時可以對狀態(tài)進(jìn)行處理,輔助函數(shù)mapGetters.
3, Mutation 修改狀態(tài) (修改變量的值)
4,action 觸發(fā) mutation函數(shù) ,從而修改狀態(tài),支持異步
5,module 當(dāng)狀態(tài)很多時,把狀態(tài)分開管理。
安裝 vuex
1,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ù)
? ? ? ? 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)
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,通過輔助函數(shù) mapState 來獲取
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;
? ? }
? })
// 如果需要定義其它的計算屬性,就按照下面的寫法
computed: {
? ? // 其他的計算屬性
? ? 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;
? ? ? ? ? ? }
? ? ? })
}
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;
? ? }
}
5,修改state 中的狀態(tài)
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是新的數(shù)據(jù)
? ? ? ? */
? ? ? ? updateName(state, payload) {
? ? ? ? ? ? state.name = payload;
? ? ? ? }
? ? }
})
2,在需要的時候調(diào)用mutation 進(jìn)行修改state里的name狀態(tài)。
```
// 第一個參數(shù)是mutation的名字,第二參數(shù)是要修改成的數(shù)據(jù)
this.$store.commit('updateName','老胡');
```
綜合例子:通過Vuex實(shí)現(xiàn)加減
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;
? ? ? ? ? ? }
? ? ? ? }
? ? }
})
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>
6,vuex本地持久化
當(dāng)刷新頁面,項目重新加載,vuex會重置,所有狀態(tài)回到初始狀態(tài),使用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'
// 導(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)
? ? ? },
? ? }
})
7,modules的使用
1,配置模塊的vuex
export default {
? ? state: {
? ? ? ? cartNum: 10
? ? },
? ? getters: {
? ? },
? ? mutations: {
? ? ? ? updateCartNum(state, payload) {
? ? ? ? ? ? state.cartNum = payload;
? ? ? ? }
? ? },
? ? actions: {
? ? }
}
2,獲取狀態(tài)
<template>
? <div>{{cartNum}}</div>
</template>
<script>
import { mapState } from "vuex";
export default {
? computed: mapState({
? ? cartNum(state) {
? ? ? return state.cart.cartNum;
? ? }
? })
};
</script>
3,修改狀態(tài)
this.$store.commit("updateCartNum",200);
八) acion
Action 類似于 mutation,都是用來修改vuex的狀態(tài), 不同在于:
Action 提交的是 mutation,而不是直接變更狀態(tài)。
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的實(shí)例
? ? ? ? * @param {*} payload 修改的數(shù)據(jù)
? ? ? ? */
? ? ? ? updateNum(ctx, payload) {
? ? ? ? ? ? setTimeout(() => {
? ? ? ? ? ? ? ? ctx.commit('updateNum', payload);
? ? ? ? ? ? }, 3000)
? ? ? ? }
? ? }
})
2,派發(fā)action,在需要的地方,調(diào)用以下方法
this.$store.dispatch("updateNum",500);