Vuex2.x

112 阅读1分钟

Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

适合多个组件没有关系的时候使用,可以共享数据

基本使用

mutation-types.js

export const ADD = 'ADD'
export const REDUCE = 'REDUCE'

store.js

import Vue from "vue"
import Vuex from "vuex"
import {ADD,REDUCE} from './mutation-types';
Vue.use(Vuex)
//创建状态管理对象
let store = new Vuex.Store({
    #状态
    //定义共享变量
    state:{
        count:0,
    	todo: [
            { id: 1, text: '睡觉', done: true },
            { id: 2, text: '吃饭', done: false },
            { id: 3, text: '打豆豆', done: true },
            { id: 4, text: '敲代码', done: false }
        ]
    },
                           
    #变更状态,同步函数
    //修改共享数据
    mutations:{
    	increament:function(state,{num = 0}){
    		state.count += num
		},
        [ADD](state) {
            state.count++
        },
        [REDUCE](state) {
            state.count--
        }
	},
    
    #派生状态
    //派生属性
    getters:{
        getTodoById: (state) => {
            return (id) => {
                return state.todo.find(item => item.id === id)
            }
        }
        level:function(state){
            if(state.conut < 5){
                return "青铜"
            }else if(state.count < 10){
                return "白银"
            }else{
                return "黄金"
            }
        }    
    }
    
    #异步操作
    //通过调用mutations,间接对状态属性产生影响,而不是直接变更状态
    //action可以包含任意异步操作
    actions:{
        increamentAction:function(context){
            context.commit("increament",1)
        }    
    },
    
}),
export default store

页面调用

methods:{
    test:function(){
        //提交参数= 提交负荷 提交给mutations
        this.$store.commit({
            type:"increament",
            num:3
        })
        //调用action中的方法
        this.$store.dispatch("increamentAction")
    }
}

//html中调用
{{$store.state.count}}
{{$store.getters.level}}
<p>{{getTodoById(2).text}}</p>
<button @click="add">增加按钮</button>
<button @click="reduce">减少按钮</button>


#映射方式
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'

computed:{
    ...mapState(['count'])
    ...mapGetters(['level','getTodoById'])
}
methods:{
    ...mapMutations(["increament"]),
    ...mapMutations({
        add:'ADD',
        reduce:'REDUCE'
    })
    ...mapActions(["increamentAction"])
    onFun(){
    	this.increament()  
        this.increamentAction()
    }
}

模块化使用

index.js

import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
import moduleA from "./modules/moduleA"
import getters from "./getters"

let store = new Vuex.Store({
    getters:getters,
    modules:{
        counting:moduleA
    }
}) 
export default store

moduleA.js

export default {
    //定义共享变量
    state:{
        count:1
    },
    //修改共享数据
    mutations:{
    	increament:function(state,step){
    		state.count += step
		}
	},
    //通过调用mutations,间接对状态属性产生影响
    actions:{
        increamentAction:function(context){
            context.commit("increament",1)
        }    
    }
}

getters.js

export default{
    level:function(state){
            if(state.counting.conut < 5){
                return "青铜"
            }else if(state.counting.count < 10){
                return "白银"
            }else{
                return "黄金"
            }
    } 
}

页面调用

{{$store.state.counting.count}}
{{$store.getters.level}}

vuex的实现原理

class KStore{
    constructor(options){
        this.state = options.state;
        this.mutations = options.mutations;
        this.actions = options.actions;
        //借用vue本身的数据相应式机制
        this.vm = new Vue({
            data:{
                state:this.state
            }
        })
    }
    commit(type,payload){
        const mutation = this.mutations[type];
        mutation(this.state,payload)
    }
    dispatch(type,payload){
        const action = this.actions[type];
        const ctx = {
            commit:this.commit.bind(this),
            state:this.state,
            dispatch:this.dispatch.bind(this)
        }
        return action(ctx,payload)
    }
}

vuex实例

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations.js'
import actions from './actions.js'
import getters from './getters.js'
Vue.use(Vuex);
const state = {
    num:5
}
export default new Vuex.Store({
	state,
	getters,
	actions,
	mutations
})




mutations.js

import {GET_HOT_SHOPS} from './mutation-types.js'
[GET_HOT_SHOPS](state,list){
	state.hotShops = state.hotShops.concat(list);
},


    
mutations-types.js

export const GET_HOT_SHOPS = 'GET_HOT_SHOPS'


actions.js

import axios from 'axios'
import * as types from './mutation-types.js'
export default {
    getHotShops({commit,state}){
		state.busy = true;
		commit(types.IS_SHOW_LOADING_TIPS,true);
		axios.get('/mock/home/hot_shop.json').then((response)=>{
			commit(types.IS_SHOW_LOADING_TIPS,false);
			let result = response.data.list.slice(state.num-5,state.num);
			if(result.length !== 0){
				commit(types.GET_HOT_SHOPS,result);
				state.busy = false;
				state.num+=5;
			}else{
				commit(types.IS_SHOW_LOADED_TIPS,true);
			}
		})
	},
}






getters.js
export default{
    hotShops: state=>state.hotShops,
}

保存刷新后没有数据

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from "./mutations"
import getters from './getters'
import actions from './actions'
//import state from './state'

Vue.use(Vuex)

export default new Vuex.Store({
    state: sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')) : {
        iscollapse: false,
        IsFactory: '',
        companys: []
    },
    mutations,
    getters,
    actions,
})

APP.vue

<script>
export default {
  data() {
    return {};
  },
  mounted() {
    window.addEventListener("unload", this.saveState);
  },
  methods: {
    saveState() {
      sessionStorage.setItem("state", JSON.stringify(this.$store.state));
    },
  },
};