Vuex基础

470 阅读2分钟

一基本使用方法

/*
	1. Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
	2. 采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
*/
import Vue from 'Vue'
import Vuex from 'Vuex'
Vue.use(Vuex)

const state = {
  count : 1
}
const mutations = {
  add(state, n=0){
    state.count+=n
  },
  reduce(state){
    state.count--
  }
}

export default new Vuex.Store({
  state, 	 	//相当于Vue中的data
  mutations,	//相当于Vue中的methods,用来存储同步方法
  getters,		//相当于Vue中的computed
  actions,		//相当于Vue中的methods,用来存储异步方法
})

// Vue中调用Vuex的数据
// import store from 'store.js'
new Vue({
	store, //引入store对象
    created(){
        // 使用 .$store.state 调用 vuex中的数据
        console.log(this.$store.state.count) 
    }
})

2. mutations使用

/*	
	为了方便数据管理,Vuex中不推荐直接改变 store 中的状态。改变 store 中的状态的唯一途径就是
显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现
一些工具帮助我们更好地了解我们的应用。

	Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,
那么相应的组件也会相应地得到高效更新。

	该对象中的方法最对只支持两个参数,参数一:state状态  参数二:传递过来的参数 
*/
const mutations = {
  add(state, n=0){
    state.count+=n
  },
}
// 组件中调用 mutation 中方法的格式 this.$store.commit('方法名')
new Vue({
    created(){
        // 注意调用的参数格式
        console.log(this.$store.commit('add', 1))
    }
})
// 对象形式调用
    // 使用包含 type 属性的对象进行调用
    this.$store.commit({
      type: 'add',
      amount: 10
    })
    const mutations = {
      add(state, payload=0){
        state.count+=payload.amount
      },
    }
// 载荷形式调用
    this.$store.commit('add',{
      amount: 10
    })

3. getters

/*
	用于对外提供数据
	相当于vue中的计算属性computed
	getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
	当该对象里面的方法中使用到的state中的属性值发送变化时,该函数会自动触发
	Getter 接受 state 作为其第一个参数
	Getter 接受 getters 作为其第一个参数
*/
getters:{
    getcount(state){
    	return state.count
    }
}
// 外界调用
store.getters.getcount

4. actions

/*
	Action 类似于 mutation,不同在于:
	Action 提交的是 mutation,而不是直接变更状态。
	Action 可以包含任意异步操作。
*/

actions:{
    getcount(context){
        // 调用mutations方法
        context.commit('setmenus',data)
    }
}
// contexts是一个与 store 实例具有相同方法和属性的 context 对象,并不是store本身
// 外界调用
this.$store.dispatch('get')

// 载荷形式调用
this.$store.dispatch('get', {
    coount:1
})
// 对象形式调用
this.$store.dispatch({
    type:'get',
    count: 1
})

5. module

/*
	Vuex 允许我们将 store 分割成模块(module)。
	每个模块拥有自己的 state、mutation、action、getter
	甚至是嵌套子模块——从上至下进行同样方式的分割
	对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象
	对于模块内部的 action,根节点状态则为 context.rootState
	对于getters来说,根节点可以作为第三个参数
	模块内的getter、mutation和action若没有命名则依然注册在全局中
		可直接使用this.$store.state.carGetter方法,这是为了多个模块响应同一个mutation
		this.$store.state.模块名.属性名
	有命名时
		dispacth("changeName"),  就要变成 dispatch("login/changeName"); 
		getters.localJobTitle 就要变成 getters["login/localJobTitle"]
*/
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}
const store = new Vuex.Store({
  modules: {
    moduleA,
    moduleB
  }
})
store.state.moduleA // -> moduleA 的状态
store.state.moduleB // -> moduleB 的状态

二 辅助函数

1. mapState

1.1 基本使用

// 使用 mapState 辅助函数帮助我们生成计算属性
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
  computed: mapState({
    // 箭头函数可使代码更简练
    count: state => state.count,
    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',
    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}

1.2 简写方式

// 当映射的计算属性的名称与 state 的子节点名称相同时,可以给 mapState 传一个字符串数组。
computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])

1.3 混合使用

// 由于 mapState 返回的是一个对象,所以可以用扩展运算符进行快捷获取其中的属性
computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}

2. mapGetters

// 将 store 中的 getter 映射到局部计算属性:
import { mapGetters } from 'vuex'
export default {
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}


3. mapMutations

import { mapMutations } from 'vuex'
export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      // `mapMutations` 也支持载荷:
      'incrementBy'
      // 直接在调用的地方传入参数,扩展写法会自动将参数传递的=过去
      /* 例: this.incrementBy(amount)后会自动解析为
      		 this.$store.commit('incrementBy', amount) */
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

4. mapActions

import { mapActions } from 'vuex'
export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}