Skip to content

Vuex

vuex

开始

TIP

Vue2 使用 Vuex3

Vue3 使用 Pinia

sh
yarn add vuex@3

创建一个 store

js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
  modules
})

export default store

Vue 通过 store 选项,将状态从根组件注入到每一个子组件中,然后通过 $store 来访问

js
import store from '@/store'

new Vue({
  store
})

State

创建

js
const state = {
  count: 0
}

访问

js
export default {
  computed: {
    count() {
      return this.$store.state.count
    }
  }
}

辅助函数

js
import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState(['userinfo', 'token'])
  }
}
js
import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState({
      strCount: 'count',
      funCount: (state) => state.count,
      totalCount(state) {
        return state.count + this.localCount
      }
    })
  }
}

Getters

创建

接收两个参数

state :当前模块的 state 对象

getters :所有模块的 getters 对象

js
const getters = {
  doubleCount: (state) => state.count * 2
}

返回一个函数(不会被缓存)

js
const getters = {
  getTodoById: (state) => (id) => {
    return state.todos.find((todo) => todo.id == id)
  }
}

store.getTodoById(2)

辅助函数

js
import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters(['doubleCount'])
  }
}
js
import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters({
      count: 'doubleCount'
    })
  }
}

Mutations

创建

接收两个参数

state :当前模块的 state 对象

payload :负载,即传递的参数,可以是任意数据类型,如果有多个参数,那就传一个对象

js
const mutations = {
  SET_TOKEN(state, token) {
    state.token = token
  }
}

store.commit('SET_TOKEN', token)
js
const mutations = {
  SET_INFO(state, payload) {
    state.userinfo = payload.userinfo
    state.token = payload.token
  }
}

// 两种调用方式
store.commit('SET_INFO', { userinfo, token })

store.commit({
  type: 'SET_INOF',
  userinfo,
  token
})

辅助函数

js
import { mapMutations } from 'vuex'

export default {
  methods: {
    ...mapMutations(['SET_TOKEN']),
    ...mapMutations({
      setToken: 'SET_TOKEN'
    })
  }
}

INFO

mutation 中的 this 指向的是当前 store

所以,mutation 中可以访问 getters ,调用 mutationaction

但是,这些通常都是不建议的,且不需要的操作。

mutation 通常只用来赋值操作就行了。

mutation 中更新状态是同步操作,且必须是同步函数。

Actions

action 可以包含任意异步操作,它提交 mutation ,而不直接修改状态。

创建

接收两个参数

context :和当前 store 一毛一样,但并不是一回事,可以通过它访问 store 的所有属性和方法,可以直接用解构语法。

payload :负载,和 mutation 一样。

js
const actions = {
  updateUserinfo(context, payload) {
    const { state, getters, commit, dispatch } = context

    getUserinfo().then((res) => {
      let user = res.data
      commit('SET_USERINFO', user)
    })
  },
  update({ commit }) {
    commit('UPDATE')
  }
}

store.dispatch('updateUserinfo')

辅助函数

js
import { mapActions } from 'vuex'

export default {
  ...mapActions(['updateUserinfo']),
  ...mapActions({
    update: 'updateUserinfo'
  })
}

异步操作

js
const actions = {
  updateUserinfo({ commit }) {
    return new Promise((resolve, reject) => {
      getUserinfo()
        .then((res) => {
          let user = res.data
          commit('SET_USERINFO', user)
          resolve(user)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
}

store.dispatch('updateUserinfo').then((user) => {
  console.log(user)
})