Vuex模块化用法 跨模块调用的方式

 更新时间:2023年10月26日 09:22:47   作者:小杨闯关之情迷代码  
这篇文章主要介绍了Vuex模块化用法 跨模块调用的方式,具有很好的参考价值,希望对大家有所帮助,

准备

为了说明这个问题,我们来一起实现一个小需求

即 现在有两个module - productuser

需求为调用 product 模块的方法 去修改 user 模块的 userInfo(用户名信息)

// module user 模块
const user = {
	state: {
		userInfo: '鸣人', // 用户信息
	},
	mutations:{
		SET_UserInfo(state,payload) {
			state.userInfo = payload.userInfo
		},
	},
	actions: {
		setuserInfo(context,payload) {
			return new Promise(resolve => {
				context.commit('SET_UserInfo',payload)
				resolve();
			})
		},
	}
}

export default user

不难看出, 上述需求 其实就是在 product 模块的方法中的去调用 user模块 的 setuserInfo 方法

那我们来看看 product 模块

const product = {
	actions: {
		callsetuserInfo(context,payload) {
                // 在这里调用 user 模块的 setuserInfo 方法
		},
	}
}

export default product

接着就是注册这两个模块:

import Vue from 'vue'
//引用Vuex
import Vuex from 'vuex'
Vue.use(Vuex)

import product from '@/store/modules/product'
import user from '@/store/modules/user'
// import  getters from '@/store/modules/getters.js'
// import  actions from '@/store/modules/actions.js'



//实例store对象
const store = new Vuex.Store({
	modules: {
		product,
		user
		// getters,
		// actions
	}
})

//导出store对象
export default store

跨模块调用state

这里我们首先要了解 方法中的第一个参数 context

打印一下

发现有 commit,dispatch,getters,rootGetters,rootState 几个参数

结合官网说明:

同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState

即: context.state -> 访问的是 当前模块下的 state

context.rootState -> 是根节点状态

const product = {
	actions: {
		callsetuserInfo(context,payload) {                
                // 通过 根节点状态 去访问 user 模块的 userInfo信息
                console.log(context.rootState.user.userInfo)  // '鸣人'
		},
	}
}

export default product

跨模块调用getter

和跨模块调用state类似 ,通过 context.rootGetters去访问模块

namespaced情况区分

跨模块调用mutation,action

这里要区分 模块是否开启了命名空间 namespaced

首先来看默认情况 (没有开启namespaced)

官网说明:

  • 默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对同一个 action 或mutation 作出响应。
  • Getter同样也默认注册在全局命名空间,但是目前这并非出于功能上的目的(仅仅是维持现状来避免非兼容性变更)。
  • 必须注意,不要在不同的、无命名空间的模块中定义两个相同的getter 从而导致错误。

跨模块调用actions:

// 三个参数: 1. 模块/方法名 2.参数 3.是否从跟节点寻找
context.dispatch('需要调用的方法名',params,{root: true})

跨模块调用mutations:

// 三个参数: 1. 模块/方法名 2.参数 3.是否从跟节点寻找
context.commit('需要调用的方法名',params,{root: true})
const product = {
	actions: {
		callsetuserInfo(context,payload) {
                  // 因为是默认为全局注册  可以直接访问 setuserInfo  
                  //  {root: true} 表明从根节点寻找  如果不加 则是从当前模块中
                  //  这里即 product模块 去找 setuserInfo 方法 (当然找不到)
           		contxt.dispatch('setuserInfo',{
				userInfo: '宇智波佐助'
			},{root: true})
		},
	}
}
export default product

在页面中调用:

...mapState({
    cartList: state => state.product.cartList,
    userInfo:state => state.user.userInfo,
}),
methods: {
    // 因为为默认情况,Action全局注册,这里使用辅助函数直接取值
 ...mapActions( [
   'callsetuserInfo',
 ]),

async onLoad(params) {
    this.callsetuserInfo().then(()=> {
        // 打印user 模块 的 userInfo
        console.log(this.userInfo) //  宇智波佐助 
    })
}

打印设置值- 宇智波佐助 ,默认情况(未开启命名空间)跨模块调用actions 成功

跨模块调用mutations类似,语法糖改为 context.commit 即可

启命名空间的情况

官方文档:

  • 如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true的方式使其成为带命名空间的模块。
  • 当模块被注册后,它的所有 getter、action 及 mutation都会自动根据模块注册的路径调整命名。

例如:

const store = createStore({
  modules: {
    account: {
      namespaced: true,

      // 模块内容(module assets)
      state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
      getters: {
        isAdmin () { ... } // -> getters['account/isAdmin']
      },
      actions: {
        login () { ... } // -> dispatch('account/login')
      },
      mutations: {
        login () { ... } // -> commit('account/login')
      },

      // 嵌套模块
      modules: {
        // 继承父模块的命名空间
        myPage: {
          state: () => ({ ... }),
          getters: {
            profile () { ... } // -> getters['account/profile']
          }
        },

        // 进一步嵌套命名空间
        posts: {
          namespaced: true,

          state: () => ({ ... }),
          getters: {
            popular () { ... } // -> getters['account/posts/popular']
          }
        }
      }
    }
  }
})

官网中的 在带命名空间的模块内访问全局内容 的例子:

modules: {
  foo: {
    namespaced: true,

    getters: {
      // 在这个模块的 getter 中,`getters` 被局部化了
      // 你可以使用 getter 的第四个参数来调用 `rootGetters`
      someGetter (state, getters, rootState, rootGetters) {
        getters.someOtherGetter // -> 'foo/someOtherGetter'
        rootGetters.someOtherGetter // -> 'someOtherGetter'
        rootGetters['bar/someOtherGetter'] // -> 'bar/someOtherGetter'
      },
      someOtherGetter: state => { ... }
    },

    actions: {
      // 在这个模块中, dispatch 和 commit 也被局部化了
      // 他们可以接受 `root` 属性以访问根 dispatch 或 commit
      someAction ({ dispatch, commit, getters, rootGetters }) {
        getters.someGetter // -> 'foo/someGetter'
        rootGetters.someGetter // -> 'someGetter'
        rootGetters['bar/someGetter'] // -> 'bar/someGetter'

        dispatch('someOtherAction') // -> 'foo/someOtherAction'
        dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'

        commit('someMutation') // -> 'foo/someMutation'
        commit('someMutation', null, { root: true }) // -> 'someMutation'
      },
      someOtherAction (ctx, payload) { ... }
    }
  }
}

好了,了解之后 。回到我们的需求 = =!

模块user,product 先 开启命名空间 如下:

const user = {
	namespaced: true,
     // 后续代码
 }

在product模块 中去调用user 模块的action方法

const product = {
	actions: {
		callsetuserInfo(context,payload) {
                  // 因为开启了命名空间  访问方法 需要通过模块 user/setuserInfo  
           		context.dispatch('user/setuserInfo',{
				userInfo: '宇智波佐助'
			},{root: true})
		},
	}
}
export default product

在页面中调用

 ...mapState({
    cartList: state => state.product.cartList,
    userInfo:state => state.user.userInfo,
}),
methods: {
    // 因为为开启命名空间  不能直接访问方法
    // 普通写法
   ...mapActions([
   'product/callsetuserInfo',
 ]),  
    // 简化写法:   将模块的空间名称字符串作为第一个参数传递
 ...mapActions('product',[
   'callsetuserInfo',
 ]),
 // 如果想调用多个不同命名空间的方法
  ...mapActions('模块B',[
   '模块B Function',
 ]),
async onLoad(params) {
    this.callsetuserInfo().then(()=> {
        // 打印user 模块 的 userInfo
        console.log(this.userInfo) //  宇智波佐助 
    })
}

参考文档: https://vuex.vuejs.org/zh/guide/modules.html

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 解决vue页面DOM操作不生效的问题

    解决vue页面DOM操作不生效的问题

    下面小编就为大家分享一篇解决vue页面DOM操作不生效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue前端实现打印下载示例详解

    vue前端实现打印下载示例详解

    这篇文章主要为大家介绍了vue前端实现打印下载示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • vue做网页开场视频的实例代码

    vue做网页开场视频的实例代码

    这篇文章主要介绍了vue做网页开场视频的实例代码,需要的朋友可以参考下
    2017-10-10
  • Mint UI组件库CheckList使用及踩坑总结

    Mint UI组件库CheckList使用及踩坑总结

    这篇文章主要介绍了Mint UI组件库CheckList使用及踩坑总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • vue生命周期beforeDestroy和destroyed调用方式

    vue生命周期beforeDestroy和destroyed调用方式

    这篇文章主要介绍了vue生命周期beforeDestroy和destroyed调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • vue中v-model对select的绑定操作

    vue中v-model对select的绑定操作

    这篇文章主要介绍了vue中v-model对select的绑定操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue中循环多个li(表格)并获取对应的ref的操作代码

    vue中循环多个li(表格)并获取对应的ref的操作代码

    我想要获取每一个循环并获取每一个li(或者其它循环项)的ref,以便于后续的操作,接下来通过本文给大家分享vue中循环多个li(表格)并获取对应的ref的操作代码,感兴趣的朋友跟随小编一起看看吧
    2024-02-02
  • vue2.0 better-scroll 实现移动端滑动的示例代码

    vue2.0 better-scroll 实现移动端滑动的示例代码

    本篇文章主要介绍了vue2.0 better-scroll 实现移动端滑动的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2018-01-01
  • vue el-select绑定对象时,回显内容不正确,始终是最后一项的解决

    vue el-select绑定对象时,回显内容不正确,始终是最后一项的解决

    这篇文章主要介绍了vue el-select绑定对象时,回显内容不正确,始终是最后一项的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • vuex中能直接修改state吗

    vuex中能直接修改state吗

    当我们使用vuex的时候,时不时能看到“更改Vuex中的store中的状态唯一办法就是提交mutations”,但是有没有试想过,我们不提交mutations其实也能修改state的值?答案是可以的,下面通过本文介绍下vuex修改state值的方法,感兴趣的朋友一起看看吧
    2022-11-11

最新评论