Vuex映射方法mapState、mapGetters、mapMutations、mapActions的使用

·  阅读 1816

通过这篇文章让你彻底搞懂mapState、mapGetters、mapMutations、mapActions的使用

本文涉及知识点

  • vuex
  • Vuex模块化
  • namespace命名空间

如不了解以上知识,请自行查阅相关文章

4个映射方法(mapStatemapGettersmapMutationsmapActions)的出现,使我们不必编写大量繁琐的代码去获取vuex中的数据,简化了用户操作,提高了开发者效率,接下来我们就来看看如何使用这4个方法

基本用法

假设Vuex的代码如下:

const store = new Vuex({
    state:{
        userInfo:{
            id:110,
            username:'laoxie'
        }
    },
    getters:{
        isLogin(state){
            return !!state.userInfo.id
        }
    },
    mutations:{
        login(state,payload){
            state.userInfo = payload
        },
        logout(state){
            state.userInfo = {}
        }
    },
    actions:{
        login(ctx,payload){
            ajax('/login',payload).then(data=>{
                ctx.commit('login',data)
            })
        }
    }
})
复制代码

mapStatemapGetter映射的值都属于属性,所以一般用在computed选项中,mapMutationsmapActions映射的值都属于方法,所以一般用在methods中,它们的参数支持数组与对象用法,并返回一个对象

{
    computed:{
        // 把同名属性userInfo映射到computed中,以下两行代码等效
        // userInfo(){return this.$store.state.userInfo}
        ...mapState(['userInfo']), 
        
        // 如需更改名字,则可使用对象形式(字符串或函数形式)
        ...mapState({user:'userInfo',currentUser:state=>state.userInfo})
        
        // mapGetters采用对象参数时不支持函数写法
        ...mapGetters(['isLogin']),
        ...mapGetters({logined:'isLogin'}),
    },
    methods:{
        // 以下两种写法等效于:logout(){this.$store.commit('logout')}
        ...mapMutations(['logout']), 
        ...mapActions({
            logout(commit,payload){
                // commit固定为第一个参数
                // payload为调用logout时传入的参数,不传则为undefined
                commit('logout')
            }
        }),
        
        // 以下两种写法等效于:login(user){this.$store.dispatch('login',user)}
        ...mapActions(['login']),
        ...mapActions({
            login(dispatch,payload){
                // dispatch固定为第一个参数
                // payload为调用login时传入的参数,不传则为undefined
                dispatch('login',payload)
            }
        })
    }
}
复制代码

高级用法

假设Vuex使用了模块化及命名空间,更能体会4个映射方法的优势,假设vuex代码如下:

const user = {
    // 模块化并设置命名空间 
    namespaced:true,
    state:{
        userInfo:{
            id:110,
            username:'laoxie'
        }
    },
    getters:{
        isLogin(state){
            return !!state.userInfo.id
        }
    },
    mutations:{
        login(state,payload){
            state.userInfo = payload
        },
        logout(state){
            state.userInfo = {}
        }
    },
    actions:{
        login(ctx,payload){
            ajax('/login',payload).then(data=>{
                ctx.commit('login',data)
            })
        }
    }
}
const store = new Vuex({
    modules:{
        user
    }
})
复制代码

Vuex模块化后,默认只影响state的获取,gettersmutationsactions依然在全局状态下,设置了命名空间(namespaced:true)后getters、mutations、actions的获取与操作需要带上命名空间,操作相对会比较繁琐,使用映射方法可以简化我们的代码,用法如下:

PS: 只有设置了命名空间,映射方法才可以使用第一个参数

{
    computed:{
        // 以下两个用法效果一至
        // 不用第一个参数用法如下
        ...mapState({userInfo:state=>state.user.userInfo}),
        // 设置第一个参数为模块名称
        ...mapState('user',['userInfo']), 
        
       
        // 以下两个用法效果一至
        ...mapGetters(['user/isLogin']), // 不推荐,给实例写入`user/isLogin`属性
        ...mapGetters('user',['isLogin']), // 给实例写入`isLogin`属性
    },
    methods:{
        // 以下写法等效于:logout(){this.$store.commit('user/logout')}
        ...mapActions('user',['logout']),
        
        // 以下写法等效于:login(user){this.$store.dispatch('user/login',user)}
        ...mapActions('user',{
            login(dispatch,payload){
                // dispatch固定为第一个参数
                // payload为调用login时传入的参数,不传则为undefined
                dispatch('login',payload)
            }
        })
    }
}
复制代码

以上为mapStatemapGettersmapMutationsmapActions 4个映射方法的使用,结果模块化与命名空间更能发挥它们的优势,实际开发中大家只要多尝试就能理解到它们折精髓。

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改