Vuex的五大核心模块使用详解
Posted 忘忘碎斌bin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuex的五大核心模块使用详解相关的知识,希望对你有一定的参考价值。
Vuex的状态管理
从安装到Vuex常见使用和细节的保姆级讲解。
Vuex的基本安装与配置
- 安装:
npm install vuex@next
- 开发目录结构,在新建
src/store/index.js
路径文件。在 index.js内配置。
─src
│ App.vue
│ main.js
├─assets
│ logo.png
├─components
└─store
index.js
- Vuex的配置
index.js
import { createStore } from "vuex";
const store = createStore({
state(){return {}},
getters: {},
mutations: {},
actions: {},
modules: {}
});
export default store
main.js
use进行注册
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
createApp(App).use(store).mount('#app')
Vuex有五大核心模块:state
、getters
、mutations
、actions
和 module
。
接下来,接下来 从 template直接使用,到 Option API内的使用,再到 composition API内的使用。
核心模块一:state
基本使用
state简而言之就是用来存放一些数据,这些数据可以在任何一个页面内进行使用。
- 在 template内直接通过
$store.state
对象来取值。 - 在 Option API中 通过
this.$store.state
对象来取值。 - 在 Composition API 中:需要用到 vuex提供的useStore
<script>
import { computed } from 'vue'
import {useStore} from 'vuex'
export default {
setup(){
const store = useStore();
const address = computed( _ => store.state.address) ;
const info = computed( _ => store.state.info) ;
return {
address,
info
}
}
}
</script>
mapState的辅助函数
辅助函数:用来解决获取数据而路径太长的情况。一般是放在computed使用。
- Option API中使用辅助函数。
参数为数组时,将state内的哪些数据映射过来,就填什么,在template使用直接用数组内的名字
<script>
import { mapState} from 'vuex'
export default {
computed:{
...mapState(['address','info'])
}
}
</script>
参数为对象时,可以进行名字state数据做名字的映射,使用自定义的名字
<script>
import { mapState} from 'vuex'
export default {
computed:{
...mapState({
sInfo:'info',
sAddress: state => state.address
})
}
}
</script>
- Composition API中使用辅助函数
一个一个取
<script>
import {useStore,mapState} from 'vuex'
import {computed} from 'vue'
export default {
setup(){
const store = useStore();
const address = computed(()=>store.state.address);
const info = computed(()=>store.state.info)
return {
address,
info
}
}
}
</script>
mapState返回的是一个对象: { address:function } 直接解雇setup返回,页面内使用是一个函数。 在使用mapState时本质内部还是使用this.$store.state。但是 setup里面是没有 this 的
在取到对应函数后 手动改变this指向
<script>
import {useStore,mapState} from 'vuex'
import {computed} from 'vue'
export default {
setup(){
const store = useStore();
const storeFns = mapState(['address','info']);
let finallStore = {}
for(let fn of Object.keys(storeFns)){
const fun = storeFns[fn].bind({$store:store})
finallStore[fn] = computed(fun)
}
return {
...finallStore
}
}
}
</script>
其实可以封装成一个函数,但是可以和 getters的辅助函数一起封装,后面一起封装。
核心模块二:getters
在 store/index.js state中加入一条数据。
books: [{ name: 'Vuejs入门到放弃', prices: 60 }, { name: 'JS高级', prices: 50 }, { name: 'nodejs', prices: 55 }]
其他页面可能会用到 计算书的总价格。为了避免在不同的页面都写同样的求和逻辑,可以在 getters内完成一个求和的逻辑,其他页面只需要直接引用就可。
基本使用
getters: {
booksPrice(state) {
return state.books.reduce((preV, newV) = >{
return preV + newV.prices
},
0)
}
}
- 在 template内直接通过
$store.getters
对象来取值。 - 在 Option API中 通过
this.$store.getters
对象来取值。 - 在 Composition API 中:需要用到 vuex提供的useStore
<script>
import { computed } from 'vue'
import { useStore } from "vuex";
export default {
setup(){
const store = useStore();
const bookPrice = computed(()=> store.getters.booksPrice)
return {
bookPrice
}
}
}
</script>
mapGetters的辅助函数
辅助函数:用来解决获取数据而路径太长的情况。一般是放在computed使用。
mapGetters传入对象,自定义名字
- Option API中使用辅助函数。
import { mapGetters } from "vuex";
...
computed:{
...mapGetters(['booksPrice'])
}
- Composition API中使用辅助函数
与state一样,需要手动修改this指向
<script>
import { useStore,mapGetters} from "vuex";
import { computed } from "vue";
export default {
setup(){
const store = useStore();
let finallStore = {}
const storeFns = mapGetters(['booksPrice'])
for(let fn of Object.keys(storeFns)){
const fun = storeFns[fn].bind({$store:store});
finallStore[fn] = computed(fun);
}
return {
...finallStore
}
}
}
</script>
封装
getters的第二个参数
getters里面的方法,可能又依赖getters里的另一个方法,第二个参数就是整个getters对象,通过 .
的方法使用其他方法。
核心模块三:mutations
用来修改state里面的值,在mutations里面设置方法,然后再组件内提交方法名,调用对应的方法,修改对应的state内的属性值。
基本使用
- 在mutations内设置相应的方法。 第一个参数 state:可以取到state内的值,第二个参数:payload,在提交时取到传递过来的参数。
mutations: {
changeCounter(state, payload) {
state.counter = state.counter + payload
}
}
- 在 **option API **内使用
通过 commit方法提交
methods: {
increment() {
this.$store.commit('changeCounter', 1)
}
}
另一种提交风格
methods: {
increment() {
this.$store.commit({
type: 'changeCounter',
num: 1
})
}
}
- 在 composition API中使用。通过 useStore方法取到 store后 里面同样有 commit 方法。
<script>
import { useStore} from "vuex";
export default {
name: "Home",
setup(){
const store = useStore()
const increment = ()=>{
store.commit('changeCount',1);
}
const decrement = _=>{
store.commit({
type:'changeCount',
num:-1
})
}
return{
increment,
decrement
}
}
}
</script>
mapMutations辅助函数
直接映射到方法中。
mapMutations传入对象,自定义名字
- 在 **option API **内使用
import {mapMutations} from "vuex";
......
methods: {
...mapMutations(['changeCounter']),
// 自定义名字
...mapMutations({
aChangeCounter :'changeCounter'
})
}
- 在 composition API中使用
直接返回
<script>
import {mapMutations} from 'vuex'
export default {
setup(){
return {
...mapMutations(['changeCounter'])
}
}
}
</script>
or
<script>
import {mapMutations} from 'vuex'
export default {
setup(){
const useMutations = mapMutations(['changeCounter'])
return {
...useMutations
}
}
}
</script>
Mutation常量类类型
- mutation-type.js
- store/index.js中
import { INCREMENT } from "./mutation-type";
.......
mutations: {
[INCREMENT](state, payload) {
state.counter = state.counter + payload
}
}
- 组件内
import { INCREMENT } from "../store/mutation-type";
......//此处代码省略
...mapMutations([INCREMENT])
核心模块四:actions
假如数据的改变,是在异步函数操作之后,在actions内编写异步函数,再在actions内提交给mutations对state做出改变。主要是为了在配合Vue devtools 使用时,都能监听到数据改变的细节
基本使用
- 在actions内设置相应的方法,第一个参数 context上下文,和上面的的第一个参数不是一个意思,context包含的东西更多,整个store对象。第二个参数payload,在提交时取到传递过来的参数。
异步操作用定时器代替。
actions: {
delayChangeCount(context, payload) {
console.log(context);
setTimeout(_ = >{
context.commit('changeCount', typeof payload === 'object' ? payload.num: payload)
},
1000)
}
}
- 在option API内使用
通过dispatch提交
methods: {
increment() {
this.$store.dispatch('delayChangeCount', 1)
}
}
另一种提交风格
methods: {
decrement() {
this.$store.dispatch({
type: 'delayChangeCount',
num: -1
})
}
}
-
在 composition API内使用
通过 vuex提供的 useStore
<script>
import { useStore,mapActions } from "vuex";
export default {
name: "Home",
setup(){
const store = useStore();
const increment = _=>{
store.dispatch('delayChangeCount',1)
}
// 第二种提交风格
const decrement = _=>{
store.dispatch({
type:'delayChangeCount',
num:-1
})
}
return{
increment,
decrement
}
}
}
</script>
mapActions辅助函数
直接将actions内的函数映射到组件内。
- 在 option API中
import { mapActions } from "vuex";
methods: {
...mapActions(['delayChangeCount']);
}
- 在 composition API中
直接返回 or 先赋值对象,再结构返回
<script>
import {mapActions } from "vuex";
export default {
name: "Home",
setup(){
return{
...mapActions(['delayChangeCount'])
}
}
}
</script>
核心模块五:modules
假如整个项目放在一个state内,如果数据很多,可能会出现命名冲突,代码混乱的一些问题,通过modules进行分模块
基本使用
store/index.js
// 自定义的两个模块
import moduleA from './module/moduleA'
import moduleB from './module/moduleB'
// ......代码省略
modules: {
a: moduleA,
b: moduleB
}
./module/moduleA.js
基本结构和index的结构差不多
export default {
state() { return { count:100 } },
getters: {},
mutations: {},
actions: {},
modules: {}
}
组件内使用
- 使用state时 ,使用 moduleA内的state的数据:
$store.state.a.xxxx
,a 与再 modules内设置的key有关。 - 使用模块内的getters、mutations、actions也
默认注册在全局命名空间
,不需要加模块名字了,直接调用使用。
module的命名空间
因为使用模块内的getters、mutations、actions是直接使用,但是希望模块具有更高的封装度和复用性,添加 namespaced: true (在子模块内添加)的方式使其成为带命名空间的模块,那么再使用getters、mutations、actions的时候就需要一定的调整
获取模块内getters
在模块内定义方法:四个参数
state
本模块的stategetters
本模块内的gettersrootState
根模块内的staterootGetters
根模块内的getters
getters: {
getACount(state, getters, rootState, rootGetters) {
console.log(rootgetter);
return state.aCount * 2 + rootstate.count * 10
}
}
- 在template使用
<h5>moduleA getACount :{{$store.getters["a/getACount"]}}</h5>
- 在options API内使用
computed: {
getModuleACounte() {
return this.$store.getters["a/getACount"]
}
}
- 在 composition API中使用
<script>
import { computed } from "vue";
import { useStore } from "vuex";
export default {
name: "Home",
setup(){
const store = useStore();
const aCount = computed(_=>store.getters["a/getACount"]);
return{
aCount
}
}
}
</script>
提交模块内的mutations
在模块mutations内定义方法 参数和 核心模块三 内的参数解释一样
mutations: {
changeACount(state, payload) {
state.aCount++;
}
}
提交: 同样有两种提交代码的风格
**commit存在第三个参数[可选] **{root:true}
是否派发个根组件
- 在options API中
this.$store.commit('a/changeACount',1)
- 在 composition API中
<script>
import { useStore } from "vuex";
export default {
name: "Home",
setup(){
const store = useStore();
const increment = ()=> {
store.commit('a/changeACount',1)
}
return{
increment
}
}
}
</script>
提交模块内的 actions
在模块actions内定义方法, context上下文(下面详细解释), payload 携带参数
-
commit
: 提交函数 -
dispatch
:提交函数 -
getters
: 本模块内的getters -
rootGetters
: 根模块内的getters -
roo
以上是关于Vuex的五大核心模块使用详解的主要内容,如果未能解决你的问题,请参考以下文章