# Vue项目添加Vuex

# 安装

npm install vuex --save

# 添加vuex

# 1、创建store文件

在src目录下创建store文件来添加vuex实例,如下面目录所示。如果数据多可以拆分多个模块进行添加,甚者可以把单个的模块拆分成state.js、mutation.js、action.js小模块也是可以。一切为了规范和快捷。

store目录

└── src
  ├── main.js
  ├── router
  │   ├── router.js
  │   └── ...  
  └── store                 # store文件
      ├── index.js          # 创建vuex实例、组装模块、导出store实例
      ├── modules           # 子模块
      └── mutation-types.js # 根级别的 mutation types

子模块

└── store
  ├── index.js          # 创建vuex实例、组装模块、导出store实例
  ├── modules
  │   ├── publicVuex.js     # 公共子模块
  │   └── empower.js        # 其他模块
  └── mutation-types.js # 根级别的 mutation types

store/index.js文件

/**
 * @desc 状态管理器入口
 * @author xxx
*/
import Vue from 'vue'
import Vuex from 'vuex'
import publicVuex from './modules/public'
import empower from './modules/empower'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    publicVuex,
    empower
  }
})

store/modules/public.js子模块

/**
 * @desc 状态管理器 - 公共数据
 * @author xxx
*/
const publicVuex = {
  state: {
    userId: '',
    spaceRecord: ''
  },

  mutations: {
    setUserId (state, userId) {
      state.userId = userId
    },
    setSpaceRecord(state, spaceRecord) {
      state.spaceRecord = spaceRecord
    }
  },
  getters: {},
  actions: {}
}

export default publicVuex

# 2、引入

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

# 使用

# 1、在组件中使用

在不分模块的情况下,直接使用mapState映射出一个数组,就可以获取state中的数据,这其中也可以获取整个模块的state。在分模块的时候就需要使用对象来映射出模块下的state数据。

const moduleA = {
  state: {
    userId: 1,
    userName: 'bbb'
  },

  mutations: {
    setUserId (state, userId) {
      state.userId = userId
    }
  },
  getters: {},
  actions: {}
}

const store = new Vuex.Store({
  state: {
    root: '111',
    userName: 'aaa' // 根节点
  },
  mutations: {
    setRoot(state, root) {
      state.root = root
    }
  },
  modules: {
    moduleA
  }
})

获取state数据需要区分模块,如果根节点下的state数据和子模块名相同,则会直接替换成子模块,根节点下的数据不生效,如果同名最好映射时取不同的名称。调用mutations方法,可以不用区分模块进行直接调用,但会同时调用所有模块中的同名方法。

import { mapState, mapMutations } from 'vuex'

export default {
  computed: {
    // 映射根节点和子模块数据
    ...mapState(['root', 'moduleA']),
    ...mapState({
      userId: state => state.moduleA.userId
    })
    // 根节点和子模块重名
    ...mapState({
      rootUserName: 'userName',
      childUserName: state => state.moduleA.userName
    })
  },
  created() {
    console.log(this.root) // 111
    console.log(this.moduleA) // { userId: 1, userName: 'bbb' } 子模块整体数据
    console.log(this.userId) // 1

    console.log(this.rootUserName) // aaa
    console.log(this.childUserName) // bbb
  },
  methods: {
    ...mapMutations(['setRoot', 'setUserId']),

    setUserIdFn() {
      this.setRoot('xxxx')
      this.setUserId(100)
    }
  }
}

# 2、在 js引入使用

如同在vue组件中使用一样,在main.js引入store实例,注册到vue中就可以通过vue实例this来调用store的方法和数据。我们在js中使用也是通过引入store实例,直接通过实例调用vuex方法,只是不能使用map函数。

// test.js
import store from '@/store'

// 获取数据
store.state.root
// 调用mutation
store.commit('setRoot', 'xxx')

参考链接:

Vuex官方文档 (opens new window) Vuex状态管理器 (opens new window)