自从 vue2 升级到 vue3 之后,vue-router 从 3.x 升级到了 4.x,vuex 也从 3.x 升级到了 4.x。自从语法发生了较大的变化之后,其他的生态库也必须同步更新了。
现在的 vuex 版本是 4.0.0-rc.2,目前还是预览版本,可以通过下面的命令安装:
npm install vuex@next --save
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
上面代码是 vuex3 版本的形式,而 vuex4 发生了变化:
import { createApp } from 'vue'
import { createStore } from 'vuex'
// 创建 store 容器实例.
const store = createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})
const app = createApp({ /* your root component */ })
// 通过 use 注册插件
app.use(store)
通过对比我们发现,创建 store 之前是通过 new 实例来创建,现在是通过 createStore 这个工厂函数来创建实例,还有就是 use 在使用插件的时候,之前是直接传入 vuex 作为参数,而现在传入的参数是创建出来的实例。
现在,你可以通过 store.state
来获取状态对象,以及通过 store.commit
方法触发状态变更:
store.commit('increment')
console.log(store.state.count) // -> 1
为了在 Vue 组件中访问 this.$store
属性,你需要为 Vue 实例提供创建好的 store。Vuex 提供了一个从根组件向所有子组件,以 store 选项的方式“注入”该 store 的机制。这是 vuex 3.x 版本的使用方式了,但是升级 vuex 4.x 版本之后不再需要这样做了而是可以直接使用了。
new Vue({
el: '#app',
store: store,
})
现在我们可以从组件的方法提交一个变更:
methods: {
increment() {
this.$store.commit('increment')
console.log(this.$store.state.count)
}
}
在 setup() 内部,this 不会是该活跃实例的引用,所以如果是在 setup 函数中,需要使用 useStore 函数。这是一个新增的 API 。
import { useStore } from 'vuex'
export default {
setup () {
const store = useStore()
}
}
State 和 Getters 的用法:
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup () {
const store = useStore()
return {
// 在 computed 函数中访问一个 state
count: computed(() => store.state.count),
// 在 computed 函数中访问一个 getter
double: computed(() => store.getters.double)
}
}
}
Mutations 和 Actions 的用法:
import { useStore } from 'vuex'
export default {
setup () {
const store = useStore()
return {
// 访问一个 mutation
increment: () => store.commit('increment'),
// 访问一个 action
asyncIncrement: () => store.dispatch('asyncIncrement')
}
}
}
组件中通过访问 this.$store
属性可以访问 store 容器,如果使用的是 composition API 使用 useStore 代替即可。
其他的用法和之前大同小异,主要注意上面提到的3个变化。