Vue3 - Vuex中的命名空间module使用(三)
什么是命名空间?Vuex为了解决状态特别多造成store对象非常复杂的时候,允许将store分割成模块(module)每个模块都可以拥有自己的state、mutation、action、getter使用示例namespaced 命名空间关键字(用在模块的js文件里)namespaced : truestore 文件夹下新建modules文件夹新建home.jsexport default cons
·
什么是命名空间?
Vuex为了解决状态特别多造成store对象非常复杂的时候,允许将store分割成模块(module)
每个模块都可以拥有自己的state、mutation、action、getter
使用示例
namespaced 命名空间关键字(用在模块的js文件里)
namespaced : true
store 文件夹下新建modules文件夹
- 新建home.js
export default const homeModule ={
namespaced:true ,// 命名空间
state(){
return {
homeCounter:100,
}
},
getters:{
// 命名空间里面,getters,新增了2个参数 rooteState,rootGetters
doubleHomeCounter(state){
return state.homeCounter*2
}
},
mutations:{
increment(state,payload){
state.homeCounter++
}
},
actions:{
incrementAction({commit}){
commit("increment")
commit("increment",null,{root:true}) // 在模块里调用state根的mutations里面的方法
}
}
}
store 文件夹下 index.js
import {createStore} from 'vuex'
import homeModule from './modules/home'
const store = createStore({
state(){
return{
rootCounter:0
}
},
mutaions:{
increment(state){
state.rootCounter++
}
},
modules:{
home:homeModule
}
})
export default store
home组件内使用state 属性和 homeModule 模块属性
<template>
<h2> state根数据: {{$store.state.rootCounter}}</h2>
<h2>home 模块中的数据:{{$store.state.home.homeCoutner}}</h2>
<h2> doubleCounter {{$store.getters["home/doubleHomeCounter"]}}</h2>
<button @click='homeIncrement'>homeCounter + 1</button>
<button @click='homeIncrementAction' > homeCounter +1 </button>
</template>
<script>
export default{
methods:{
homeIncrement(){
this.$store.commit("home/increment")
// 直接调用mutations里方法修改homeCounter
//如果不加模块名home,那么模块里和根里 同名increment会造成多个state值改变。用了命名空间就不会了
},
homeIncrementAction(){
this.$store.dispatch("home/incrementAction") // 通过actions里方法调用mutatons修改homeCounter
}
}
}
</script>
- 使用createNamespacedHelpers
关键代码 :
const {mapState,mapGetters,mapMutations,mapActions} = createNamespacedHelpers("home")
<template>
<h2>{{homeCounter}} </h2>
<h2> {{doubleHomeCounter}} </h2>
<button @click='increment'>homeCounter+1</button>
<button @click='incrementAction'>homeCounter+1</button>
</template>
<script>
import {createNamespacedHelpers} from 'vuex'
import {useState,useGetters} from '../ hooks/index'
const { mapState, mapGetters, mapMutations, mapActions } = createNamespacedHelpers("home")
export default{
computed:{
...mapState(["homeCounter"]),
...mapGetters(["doubleHomeCounter"])
},
methods:{
...mapMutations(["increment"]),
...mapActions(["incrementAction"])
},
或者
setup(){
const state = useState(["rootCounter"]) // 根数据
const rootGetters = useGetters(["doubleRootCounter"])
const homeCounter = useState("home",["homeCounter"]) // home模块的数据
const doubleHomeCounter = useGetter("home,["doubleHomeCounter"])
const increment = mapMutations(["increment"])
const incrementAction = mapActions(["incrementAction"])
return{
...state,
...rootGetters,
...homeCounter,
...doubleHomeCounter,
...increment,
...incrementAction
}
}
}
</script>
补充
组件内使用模块的三种写法
- 写法一
computed:{
...mapState({
homeCounter:state => state.homeCounter
}),
...mapGetters({
doubleHomeCounter :"home/doubleHomeCounter"
})
}
methods:{
...mapMutations({
increment:"home/increment"
}),
...mapActions({
incrementAction:"home/incrementAction"
})
}
- 写法二
computed:{
...mapState("home",["homeCounter"]),
...mapGetters("home",["doubleHomeCounter"])
},
methods:{
...mapMutations("home",["increment"]),
...mapActions("home",["incrementAction"]),
}
- 写法三
import {createNamespacedHelpers} from 'vuex'
const {mapState,mapGetters,mapMutatons,mapActions} = createNamespacedHelpers("home")
computed:{
...mapState(["homeCounter"]),
...mapGetters(["doubleHomeCounter"])
},
methods:{
...mapMutations(["increment"]),
...mapActions(["incrementAction"]),
}
在 setup里使用
setup(){
const state = useState(["homeCounter"])
const getters = useGetters(["doubleHomeCounter"])
const mutations = mapMutations(["increment"])
const actions = mapActions(["incrementAction"])
retrn{
...state,
...getters,
...mutations,
...actions
}
}
改造之前的hooks
useState.js 支持模块化数据
import {mapState,createNamespacedHelpers} from 'vuex'
import {useMappers} from './useMappers'
export function useState(moduleName,mapper){
let mapperFn = mapState
if(typeof moduleName === 'string' && moduleName.length>0){
mapperFn = createNamespacedHelpers(moduleName).mapState ;// moduleName 就是模块的名字
}else{
mapperFn = moduleName
}
return useMapper(mapper,mapperFn)
}
useMapper.js (没改)
import {computed} from 'vue'
import {useStore} from 'vuex'
export function useMapper(mapper,mapFn){
const store = useStore()
const storeStateFns = mapFn(mapper) // 如果是useState调用的,那么这里就相当于 mapState(传过来的要拿的state名称,可能是数组可能是对象,返回结果是一个对象 {name:function,age:function}
const storeState = {}
Object.keys(storeStateFns).forEach(fnKey =>{
const fn = storeStateFns[fnKey].bind({$store:store})
storeState[fnKey] = computed(fn)
})
return storeState
}
更多推荐
已为社区贡献3条内容
所有评论(0)