vuex的使用详解

在SPA单页面组件的开发中 Vue的vuex和React的Redux 都统称为同一状态管理。简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一个组件里进行获取、进行修改,并且你的修改可以得到全局的响应变更。

vuex的五个对象

state:存储状态。也就是变量;
定义

new Vuex.Store({
    state: {
        allProducts: []
    }
    //...
})

组件中获取

this.$store.state.allProducts

getters:和vue的computed差不多,是state数据的二次包装;
定义

getters: {
    cartProducts(state, getters, rootState) 
        => (getters.allProducts.filter(p => p.quantity))
}

组件中获取

this.$store.getters.cartProducts

mutations:这是vuex中唯一修改state的方式,但不支持异步操作。第一个参数默认是state。
定义

mutations: {
    setProducts (state, products) {
        state.allProducts = products
    }
}

组件中使用

this.$store.commit('setProducts', {//..options})

actions:和mutations类似。用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作。
定义(shop为api)

actions: {
    getAllProducts ({ commit }, payload) {
        shop.getProducts((res) => {
            commit('setProducts', res)
        })
    }
}

组件中使用

this.$store.dispatch('getAllProducts', {//..payload})

modules:store的子模块,类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护。
定义

const moduleA = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
}

const moduleB = {
    state: { ... },
    mutations: { ... },
    actions: { ... }
}

const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    }
})

组件中使用

store.state.a //moduleA 的状态
store.state.b //moduleB 的状态

辅助函数

在组件中使用store中的数据或方法时,按照上面的说法,每次都要this.$store.的方式去获取,有没有简单一点的方式呢?辅助函数就是为了解决这个问题

// 组件中注册
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

export default {
    computed: {
        // 数组形式,当映射的计算属性的名称与 state 的子节点名称相同时使用
        ...mapState(['allProducts'])
        // 对象形式,可重命名 state 子节点名称
        ...mapState({
            products: state => state.allProducts
        })
        // 下面为了简便,均以数组形式使用
        ...mapGetters(['cartProducts'])
    },
    methods: {
        ...mapMutations(['setProducts']),
        ...mapActions(['getAllProducts'])
    }
}

// 组件中使用
// 变量
this.allProducts
this.products
// 方法
this.setProducts()
this.getAllProducts()

vuex的使用:

├── index.html
├── main.js
├── components
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── state.js          # 跟级别的 state
    ├── getters.js        # 跟级别的 getter
    ├── mutation-types.js # 根级别的mutations名称(官方推荐mutions方法名使用大写)
    ├── mutations.js      # 根级别的 mutation
    ├── actions.js        # 根级别的 action
    └── modules
        ├── m1.js         # 模块1
        └── m2.js         # 模块2

1.首先在vue-cli项目中安装 vuex :

npm install vuex --save

2.然后 在src文件目录下新建一个名为store的文件夹,在store文件夹里新建js文件
state.js:

const state = {
    name: 'weish',
    age: 22
};

export default state;

getters.js
(我们一般使用getters来获取state的状态,而不是直接使用state)

export const name = (state) => {
    return state.name;
}

export const age = (state) => {
    return state.age
}

export const other = (state) => {
    return `My name is ${state.name}, I am ${state.age}.`;
}

mutation-type.js
(我们会将所有mutations的函数名放在这个文件里):

export const SET_NAME = 'SET_NAME';
export const SET_AGE = 'SET_AGE';

mutations.js

import * as types from './mutation-type.js';

export default {
    [types.SET_NAME](state, name) {
        state.name = name;
    },
    [types.SET_AGE](state, age) {
        state.age = age;
    }
};

actions.js
(异步操作、多个commit时)

import * as types from './mutation-type.js';

export default {
    nameAsyn({commit}, {age, name}) {
        commit(types.SET_NAME, name);
        commit(types.SET_AGE, age);
    }
};

modules–m1.js
(如果不是很复杂的应用,一般来讲是不会分模块的)

export default {
    state: {},
    getters: {},
    mutations: {},
    actions: {}
};

index.js
组装vuex

import vue from 'vue';
import vuex from 'vuex';
import state from './state.js';
import * as getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
import m1 from './modules/m1.js';
import m2 from './modules/m2.js';
import createLogger from 'vuex/dist/logger'; // 修改日志

vue.use(vuex);

const debug = process.env.NODE_ENV !== 'production'; // 开发环境中为true,否则为false

export default new vuex.Store({
    state,
    getters,
    mutations,
    actions,
    modules: {
        m1,
        m2
    },
    plugins: debug ? [createLogger()] : [] // 开发环境下显示vuex的状态修改
});

3.在vue实例中注入vuex

import store from './store/index.js';

new Vue({
  el: '#app',
  store,
  render: h => h(App)
});

应用场景

购物车
商品增减时,库存变化,购物车列表和金额变化
清空购物车时,所有数据还原

猜你喜欢

转载自blog.csdn.net/lixinyi0622/article/details/84993121