vuex使用总结

263 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

最近入职了新公司,很多时候都用到了vuex,但是使用过程中发现,自己对于vuex 基础知识还有所欠缺,故记录(vuex官网

image.png

核心模块

💡 state、mutation、action、getter、module

state

存储数据的,全局状态管理

定义

state:{
	userName:''
}

文件中获取方式

// 第一种方式
this.$store.state.userName

// 第二种方式
import { mapState } from "vuex";

computed:{
	...mapState(['userName'])
}

getter

state派生出的一些状态,用于页面展示,比如对列表进行过滤和数据展示

const store = createStore({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos (state) {
      return state.todos.filter(todo => todo.done)
    }
  }
})

通过方法访问

this.store.getters.doneTodos

通过辅助函数(mapGetters)访问

import { mapGetters } from 'vuex'

computed:{
	// 获取doneTodos
	...mapGetters(['doneTodos'])

	// 重命名
	...mapGetters({
	  doneTodos: 'doneTodosList'
	})
}

mutation

修改状态,一般不能修改状态(单向数据流),需要调用此函数

const store = createStore({
  state: {
    count: 1
  },
  mutations: {
    increment (state, num) {
      // 变更状态
      state.count = state.count + num
    }
		// 传参
		setCount(state, n){
			state.count = state.count + n
		}
  }
})

通过方法访问

// 第一种方式
store.commit('increment', 10)

// 第二种方式
store.commit({
  type: 'increment',
  num: 10
})

通过辅助函数(mapMutations )访问

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment' // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

action

异步操作,一般用于调用后端接口使用

actions: {
  async increment ({ commit }) {
		let num = await getNum()
    commit('increment', num)
  }
}

通过方法访问

store.dispatch('increment')

通过辅助函数访问

import { mapActions } from 'vuex'

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

module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

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 的状态

用途: 一般在存储存储比较大的使用,比如后台管理系统,会将vuex分为user.js、sys.js、permission.js等等,如下图

image.png

store/index.js中引入

import Vue from 'vue'
import Vuex from 'vuex'

import app from './modules/app'
import user from './modules/user'

import demo from './modules/demo'
import sys from './modules/sys'
import roadflow from './modules/roadflow'
import client from './modules/client'

import psm from './modules/psm'

// default router permission control
// import permission from './modules/permission'

// dynamic router permission control (Experimental)
import permission from './modules/async-router'
import getters from './getters'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    app,
    user,
    permission,
    demo,
    sys,
    roadflow,
    client,
    psm
  },
  state: {},
  mutations: {},
  actions: {},
  getters
})

在项目中使用方法

一般是【module/xxxx】使用,比如action

// permission.js模块,getUserInfo方法
store.dispatch('permission/getUserInfo', clientWidth)

在mutation中也类似

image.png

store.commit('global/setClientWidth', clientWidth)