一文搞定Vuex仓库与数据访问

当我们想要在vue框架下实现数据传输自由时,我们学习了父子传递和非父子组件通信,但是数据从哪来,这要求数据的存储需要有一个规范的仓库,这个仓库就是vuex,如何创建一个仓库:

1.我们在src下创建一个store文件夹用于存储各种数据,并创建一个index.js用于创建全局仓库数据。

2.编写index.js

import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {

  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    cart
  }
})

index.js包含五个部分:

1.state数据:这部分用来写用于存储的基本数据

2.getters:类似于computed属性,用来返回计算好的数据

3.mutations:这部分类似于方法,用于直接操作state里的数据

4.actions:这部分用于异步操作数据,如axios访问或者计时器处理为异步操作,一般在actions里会调用mutations里的方法,用来异步操作数据(mutations不能进行异步操作)

5.modules:模块数据,用来将其他模块化仓库整合到index.js中

需要注意的是,以上五类都是写在index.js中或者模块仓库js中的以及被封装好的,在文件内直接调用处理数据。其本身是需要被组件进行调用的,

1其中state类似于data(),要return 仓库数据。

2mutations里的方法第一个参数为state,(可以换别的名字,但是怎么换都是指代state),我们用这个state.数据名 可以用来获取仓库的数据并操作。第二个参数是用户可以操作的传入参数。注意,最多除了state,只能写一个参数,如果想要传递多个操作数据可以传一个对象或者数组。

3actions:用于进行异步操作,相当于对mutations做一个包装,完成其不能完成的异步操作,注意,actions里的第一个参数为context上下文,当使用actions调用mutations的方法时要用context.commit(‘mutations方法名’,操作参数(可选))

4.getters:相当于computed属性,计算state的各个值等待被调用

5.modules:当开发大型项目时,我们不方便把一大堆数据全都堆到index.js,十分不方便维护,我们可以像导入组件那样,把vuex模块化,我们在store下创建modules,在modules下写各个子组件的js代码,其写法就和index.js差不多了

import axios from 'axios'

export default {
  namespaced: true,
  state () {
    return {
      cartlist: []
    }
  },
  mutations: {
    updatelist (state, newlist) {
      state.cartlist = newlist
    },
    UpdateCount (state, obj) {
      const thisobj = state.cartlist.find(item => item.id === obj.id)
      thisobj.count = obj.newCount
    }
  },
  actions: {
    async getlist (context) {
      const newlist = await axios.get('http://localhost:3000/cart')
      // console.log(newlist.data)
      context.commit('updatelist', newlist.data)
    },
    async updateListAs (context, obj) {
      console.log(obj)
      await axios.patch(`http://localhost:3000/cart/${obj.id}`, { count: obj.newCount })
      context.commit('UpdateCount', obj)
    }
  },
  getters: {
    totalCount (state) {
      return state.cartlist.reduce((sum, item) => sum + item.count, 0)
    },
    totalPrice (state) {
      return state.cartlist.reduce((sum, item) => sum + item.price * item.count, 0)
    }
  }
}

上面写的五种方法都是写在仓库js中的,我们需要在组件内调用。如何调用分为两大类方法:

直接原生调用和map辅助函数调用

1.state调用

1)state的直接调用

在组件使用state时,模块中直接调用{{$store.state.数据名}}

script内调用多加一个this:this.$store.state.数据名

2)state的mapstate调用

import { mapState } from 'vuex'

然后再computed内写

computed:{
...mapState(['totalCount', 'totalPrice'])
}

这样组件就可以直接调用totalCount和totalPrice了

2.getters的调用

1)getters的直接调用

与state很相似。在组件使用state时,模块中直接调用{{$store.getters.数据名}}

script内调用多加一个this:this.$store.getters.数据名

2)getters的mapgetters调用

import { mapGetters} from 'vuex'

computed:{
...mapGetters(['totalCount', 'totalPrice'])
}

这样就可以直接调用{{totalCount}}获取计算属性了

3.mutations的调用

1)mutations的直接调用

我们再组件内调用mutations时,使用commit函数

如:this.$store.commit('方法名',传入参数)

2)mutations的mapMutations调用

与其他映射辅助函数类似,第一步先引入,但是第二步展开要写在method里,不同于state和getters写在 computed里

methods:{
...mapMutations(['GetList'])
}

4.actions的调用

1)还是,先是直接调用,使用dispatch,除此之外,与mutations一样

语法:this.$store.dispatch('方法名',参数)

2.actions的mapActions调用

methods:{
...mapActions(['GetList'])
}

小结

综上所述,使用map映射辅助函数可以极大的提升效率,但切记要引入什么辅助函数就写什么。

import { mapGetters, mapActions, mapMutations, mapState } from 'vuex'