vue - 使用Vuex管理状态

307 阅读3分钟
  • 安装Vuexnpm install vuex --save用来管理从后台获取的状态数据
  • 以下代码以首页Msite为例

1. 创建Store(核心仓库)

  • 在项目的store文件夹下新建index.js
/*
vuex最核心的管理对象store
 */
// 首先引入Vue及Vuex
import Vue from 'vue'
import Vuex from 'vuex'

// 引入四个基本模块
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'

// 一定要声明使用插件
Vue.use(Vuex)

// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})

2. 模块对象

2.1 State

  • 分析整理出项目首页Msite中有哪些状态需要管理,然后写入state.js
/*
状态对象 state
 */
export default {
  latitude: 40.10038, // 纬度
  longitude: 116.36867, // 经度
  address: {}, // 地址相关信息对象
  categorys: [], // 食品分类数组
  shops: [] // 商家数组
}

2.2 Mutation

  • 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation

  • 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)

  • 我们可以使用常量替代 Mutation 事件类型,新建mutations-types文件

    /*
    包含n个mutation的type名称常量
     */
    export const RECEIVE_ADDRESS = 'receive_address' // 接收地址信息
    export const RECEIVE_CATEGORYS = 'receive_categorys' // 接收分类数组
    export const RECEIVE_SHOPS = 'receive_shops' // 接收商家数组
    
  • 然后在mutations.js文件内引入使用**(注意书写格式)**

/*
vuex 的 mutations 模块
*/
import {RECEIVE_ADDRESS,RECEIVE_CATEGORYS,RECEIVE_SHOPS} from './mutation-types'

// [方法名](state,{param}){}
export default {
	[RECEIVE_ADDRESS](state, {address}) {
		state.address = address
	},
	[RECEIVE_CATEGORYS](state, {categorys}) {
		state.categorys = categorys
	},
	[RECEIVE_SHOPS](state, {shops}) {
		state.shops = shops
	}
}
  • 而回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

2.3 Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
// Action:通过操作mutation间接更新state的多个方法的对象
// 注意要引入api接口函数
import {reqAddress, reqCategorys, reqShops} from '../api'
import {RECEIVE_ADDRESS, RECEIVE_CATEGORYS, RECEIVE_SHOPS} from './mutation-types'
export default {
 // 异步获取地址
 async getAddress ({commit, state}) {
   // 从state状态中获取到经纬度用来设置reqAddress的参数(看接口文档)
   const geohash = state.latitude + ',' + state.longitude
   
   // 1. 发送异步ajax请求
   const result = await reqAddress(geohash)
   // 2. 根据结果提交一个mutation
   commit(RECEIVE_ADDRESS, {address: result.data})
 },
 // 异步获取分类列表
 async getCategorys ({commit}) {
   const result = await reqCategorys()
   commit(RECEIVE_CATEGORYS, {categorys: result.data})
 },
 // 异步获取商家列表
 async getShops ({commit, state}) {
   // 对象的解构赋值
   const {latitude, longitude} = state
   // 注意参数的顺序
   const result = await reqShops({latitude, longitude})
   commit(RECEIVE_SHOPS, {shops: result.data})
 }
}
  • 至此已经完成了首页状态数据的vuex设置

2.4 Getter

Getter 用于对 Store 中的数据进行加工处理形成新的数据

  • Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似Vue的计算属性
  • Store 中数据发生变化,Getter的数据也会跟着变化。

3. 异步获取并显示数据

  1. 在项目中注册store

    //项目的main.js文件
    import store from './store'
    
    new Vue({
    	store
    })
    
  2. 测试异步获取当前地址数据

    // 地址信息要尽早的获取,所以请求可以写在App.vue中
    // 首先删除之前测试使用封装的ajax接口的代码
    async mounted () {
        // 通过this.$store.dispatch 方法触发调用Action
        this.$store.dispatch('getAddress')
    }
    
    • 运行项目,在浏览器控制台里打开vue开发工具,切换到vuex,可以看到通过vuex异步获取的状态数据
    • 除了这种方法调用action,还可以使用mapActions语法糖
    import {mapActions} from 'vuex'
    
    async mounted () {
        this.getAddress()
    }
    methods: {
    	...mapActions(['getAddress'])
    }
    
  3. 读取并显示获取到的当前地址数据

    • 首页Msite组件中显示地址信息
    // 利用mapState语法糖去读取state对象
    import {mapState} from 'vuex'
    
    computed: {
    	...mapState(['address'])
    }
    
    <HeaderTop :title="address.name">
    // 将静态地址信息换成异步获取的地址数据 注意:title为绑定数据
    </HeaderTop>