【Vue 学习】Vuex 的使用

一、介绍

1. 什么时候使用 Vuex

多组件共享同一数据时

2. 原理图

在这里插入图片描述

二、简单使用

1. 安装 vuex 插件

vue2 使用 vuex3

npm i vuex@3

vue3 使用 vuex4

npm o vuex@4

2. 将 Vuex 插件封装成 store 对象

src/store/index.js:理论上可以随便命名

import Vue from 'vue'
import Vuex from 'vuex'
import axios from "axios";


Vue.use(Vuex)


const actions = {
    
    
    showMsgByLength(context) {
    
    
        if (context.state.msg.length >= 6) {
    
    
            // 逻辑判断完成,交给 mutations 执行函数
            context.commit('SHOW_MSG')
        } else {
    
    
            console.log('【actions  】',   context.state.msg,   'msg长度小于6')
        }
    },
    showMsgByLengthAndParams(context, value) {
    
    
        if (context.state.msg.indexOf(value) !== -1) {
    
    
            // dispatch 调用链
            context.dispatch('showMsgByLength')
        } else {
    
    
            console.log('【actions  】',   context.state.msg,   `msg不包含参数"${
      
      value}"`)
        }
    },
    sendRequest(context) {
    
    
        axios.get('https://v1.hitokoto.cn/').then(
            request => {
    
    
                context.commit('SHOW_ONE_DATA', request.data.hitokoto)
            },
            error => {
    
    
                console.log(error.message)
            }
        )
    }
}


const mutations = {
    
    
    // 命名建议:大写
    SHOW_MSG(store) {
    
    
        console.log('【mutations】',   store.msg)
    },
    SHOW_MSG_And_PARAMS(store, params) {
    
    
        console.log('【mutations】',   store.msg,   `传递的参数为"${
      
      params}"`)
    },
    SHOW_ONE_DATA(store, params) {
    
    
        console.log('请求到的每日一句为:', params)
    }
}


const state = {
    
    
    msg: 'Hello, MyComponent',
}


const getters = {
    
    
    getMsgLength(state) {
    
    
        return state.msg.length
    }
}


export default new Vuex.Store({
    
    
    actions,
    mutations,
    state,
    getters
})

3. 引入并绑定 store 对象

src/main.js:将封装的 store 对象绑定到 vue 实例身上

import store from 'src/store/index.js'


new Vue({
    
    
	el:'#app',
    // 绑定
	store,
	render: h => h(App),
    // 验证是否绑定成功
    mounted() {
    
    
		console.log(this)
	},
})

4. 使用 store 对象

methods: {
    
    
    // 直接通过 commit 执行函数【不传递参数】
    showMsg() {
    
    
    	this.$store.commit('SHOW_MSG')
    },
    // 直接通过 commit 执行函数【传递参数】
    showMsgAndParams() {
    
    
    	this.$store.commit('SHOW_MSG_And_PARAMS', '11')
    },
    // 通过 dispatch 进行逻辑判断之后再 commit 执行函数【不传递参数】
    showMsgByLength() {
    
    
    	this.$store.dispatch('showMsgByLength')
    },
    // 通过 dispatch 进行逻辑判断之后再 commit 执行函数【传递参数】
    showMsgByLengthAndParams() {
    
    
    	this.$store.dispatch('showMsgByLengthAndParams', '123456')
    },
    // 在 actions 发送请求
    sendRequest() {
    
    
    	this.$store.dispatch('sendRequest')
    }
},
computed:{
    
    
    // 展示 getters 的作用
	showGetters() {
    
    
        return this.$store.getters.getMsgLengt
    },
}

5. 细节说明

(1)上下文对象的说明

上下文对象里面封装了一些重要的数据

context = {
    
    
	commit: function(){
    
    },
    dispatch: function(){
    
    },
    getters:{
    
    },
    state:{
    
    },
    ......
}

dispatch:可以利用它实现 dispatch 调用链

showMsgByLengthAndParams(context, value) {
    
    
    if (context.state.msg.indexOf(value) !== -1) {
    
    
        // dispatch 调用链
        context.dispatch('showMsgByLength')
    } else {
    
    
        console.log('【actions  】',   context.state.msg,   `msg不包含参数"${
      
      value}"`)
    }
}

state:数据,可以进行逻辑处理

commit:保证了动作的最终执行调用

showMsgByLength(context) {
    
    
    if (context.state.msg.length >= 6) {
    
    
        context.commit('SHOW_MSG')
    } else {
    
    
        console.log('【actions  】',   context.state.msg,   'msg长度小于6')
    }
}

getters:类似于计算属性,用于所有组件复用

getMsgLength(state) {
    
    
    return state.msg.length
}

(2)在 actions 发送请求

sendRequest(context) {
    
    
    axios.get('https://v1.hitokoto.cn/').then(
        request => {
    
    
            context.commit('SHOW_ONE_DATA', request.data.hitokoto)
        },
        error => {
    
    
            console.log(error.message)
        }
    )
}

三、四个 mapXXX 的使用

上面完全足够使用了,但是 vue 还提供了简写

  • mapState
  • mapGetters
  • mapActions
  • mapMutations

借助 mapState 生成 computed,直接访问 state 数据

借助 mapGetters 生成 computed,直接访问 state 数据

computed: {
    
    
  	// 方法一:对象写法
  	...mapState({
    
    
        sum:'sum',
        school:'school',
        subject:'xueke'
    }),
        
    // OR
        
  	// 方法二:数组写法,当 state 的数据名称与生成的计算属性名称相同时,可以使用数组简写
  	...mapState([
        'sum',
        'school'
    ]),
    ...mapState({
    
    
        subject:'xueke'
    }),
}
computed: {
    
    
  	// 方法一:对象写法
  	...mapGetters({
    
    
        msgLength:'msgLength'
    }),
        
    // OR
        
  	// 方法二:数组写法
  	...mapGetters([
        'msgLength'
    ]),
}

借助 mapActions 生成 methods,直接 dispatch 到 actions 里面进行逻辑判断

借助 mapMutations 生成 methods,直接 commit 到 mutations 里面进行处理

methods:{
    
    
    // 方法一:对象写法
    ...mapActions({
    
    
        showMsgByLength:'showMsgByLength',
        showMsgByLengthAndParams:'showMsgByLengthAndParams'
    })
    
    // OR
    
    // 方法二:数组写法
    ...mapActions([
        'showMsgByLength',
        'showMsgByLengthAndParams'
    ])
}
methods:{
    
    
    // 方法一:对象写法
    ...mapMutations({
    
    
        SHOW_MSG:'SHOW_MSG',
        SHOW_MSG_And_PARAMS:'SHOW_MSG_And_PARAMS'
    }),
    
    // OR
    
    // 方法二:数组写法
    ...mapMutations([
        'SHOW_MSG',
        'SHOW_MSG_And_PARAMS'
    ]),
}

需要注意的是:使用 mapActions 和 mapMutations 时,传递参数的位置在模板绑定事件时传递,如果不手动传递参数的话,默认传递一个事件对象作为参数

四、store 的模块化

1. store 的模块化

为每个模块的配置开启命名空间

const StudentAbout = {
    
    
    // 开启命名空间
    namespaced: true,
    state: {
    
    },
    getters: {
    
    },
    actions: {
    
    },
    mutations: {
    
    }
}


const PersonAbout = {
    
    
    namespaced: true,
    state: {
    
    },
    getters: {
    
    },
    actions: {
    
    },
    mutations: {
    
    }
}


const store = new Vuex.Store({
    
    
  modules: {
    
    
    // key:value
    //	- key: 每个模块的命名空间
    //	- value:每个模块的配置
    StudentAbout: 'StudentAbout',
    PersonAbout: 'PersonAbout',
  }
})

2. 模块化之后的使用

state

getters

// 方式一:直接读取
this.$store.state.StudentAbout.stuList
this.$store.state.PersonAbout.perList


// 方式二:借助 mapState 读取
...mapState('StudentAbout',['stuList']),
...mapState('StudentAbout',{
    
    
    xueke: 'subject',
})
...mapState('PersonAbout',{
    
    
    perList: 'perList',
})
// 方式一:直接读取
// this.$store.getters.PersonAbout/nameLength
// 本来是上面这样读取,但是因为有 "/",所以改成下面的格式读取
this.$store.getters['PersonAbout/nameLength']


// 方式二:借助 mapGetters 读取
...mapGetters('PersonAbout',['nameLength'])
...mapGetters('PersonAbout',{
    
    
    nameLength: 'nameLength'
})

actions

mutations

// 方式一:直接 dispatch
this.$store.dispatch('PersonAbout/addPersonWang', person)


// 方式二:借助 mapActions:注意不要忘了参数的传递
...mapActions('PersonAbout',{
    
    
    addPersonWang:'addPersonWang',
})
// 方式一:直接 commit
this.$store.commit('PersonAbout/ADD_PERSON', person)


// 方式二:借助 mapMutations
...mapMutations('PersonAbout',{
    
    
    addPerson:'ADD_PERSON'
}),

猜你喜欢

转载自blog.csdn.net/bugu_hhh/article/details/129649178