Vue2&3全面知识总结六

感兴趣的朋友可以去我的语雀平台进行查看更多的知识。
https://www.yuque.com/ambition-bcpii/muziteng

6. Vuex

6.1 理解Vuex

6.1.1 什么是Vuex

  1. 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),

    也是一种组件间通信的方式,且适用于任意组件间通信。

  2. Vuex Github地址

Vue2&3全面知识总结六_第1张图片

Vue2&3全面知识总结六_第2张图片

6.1.2 什么时候使用Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

6.1.3 Vuex工作原理图

Vue2&3全面知识总结六_第3张图片

允许Vue Components直接到Mutations

Vue2&3全面知识总结六_第4张图片

6.2 求和案例

6.2.1 使用纯vue编写

src/App.vue




src/components/Count.vue






Vue2&3全面知识总结六_第5张图片

6.2.2 搭建Vuex环境

  1. 下载安装vuex npm i vuex
  2. 创建src/store/index.js该文件用于创建Vuex中最为核心的store
// 该文件用于创建Vuex中最为核心的store
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const actions = {}     // 准备actions---用于响应组件中的动作
const mutations = {}    // 准备mutations---用于操作数据(state)
const state = {}        // 准备state---用于存储数据

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state
})
  1. src/main.js中创建vm时传入store配置项
import Vue from 'vue' // 引入Vue
import App from './App.vue' // 引入App组件。它是所有组件的父组件
import store from "@/store";    // 引入store

Vue.config.productionTip = false

new Vue({
    render: h => h(App),    // render函数完成了这个功能:将App组件放入容器中
    store,  // 配置项添加store
    beforeCreate() {
        Vue.prototype.$bus = this;
    }
}).$mount('#app')

6.2.3 使用Vuex编写

Vuex的基本使用

  1. 初始化数据state,配置actionsmutations,操作文件store.js

  2. 组件中读取vuex中的数据$store.state.数据

  3. 组件中修改vuex中的数据$store.dispatch('action中的方法名',数据) $store.commit('mutations中的方法名',数据)

    若没有网络请求或其他业务逻辑,组件中也可越过actions,即不写dispatch,直接编写commit

src/store/index.js该文件用于创建Vuex中最为核心的store

// 该文件用于创建Vuex中最为核心的store
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const actions = {           // 准备actions---用于响应组件中的动作
    /*jia(context, value) {
        // console.log("actions中的jia被调用了", context, value)
        context.commit("JIA", value)
    },
    jian(context, value) {
        context.commit("JIAN", value);
    },*/
    jiaOdd(context, value) {
        if (context.state.sum % 2) {
            context.commit("JIA", value);
        }
    },
    jiaWait(context, value) {
        setTimeout(() => {
            context.commit("JIA", value);
        }, 500);
    }
}
const mutations = {      // 准备mutations---用于操作数据(state)
    JIA(state, value) {
        // console.log("mutations中的JIA被调用了", state, value)
        state.sum += value;
    },
    JIAN(state, value) {
        state.sum -= value;
    },
}
const state = {         // 准备state---用于存储数据
    sum: 0, // 当前的和
}

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state
})

src/components/Count.vue






6.3 getters配置项

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工,相当于全局计算属性
  2. store.js中追加getters配置
......
const getters = {
	bigSum(state){
		return state.sum * 10
	}
}

// 创建并暴露store
export default new Vuex.Store({
	......
	getters
})
  1. 组件中读取数据$store.getters.bigSum

Vue2&3全面知识总结六_第6张图片

src/store/index.js

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

Vue.use(Vuex);

// 准备actions---用于响应组件中的动作
const actions = {
    addOdd(context, value) {
        if (context.state.sum % 2) context.commit("ADD", value);
    },
    addWait(context, value) {
        setTimeout(() => {
            context.commit("ADD", value)
        }, 500)
    }
}
// 准备mutations---用于操作数据(state)
const mutations = {
    ADD(state, value) {
        state.sum += value;
    },
    SUB(state, value) {
        state.sum -= value;
    }
}
// 准备state---用于存储数据
const state = {
    sum: 0, // 当前的和
}
// 准备getters对象---用于将state中的数据进行加工
const getters = {
    bigSum() {
        return state.sum * 10;
    }
}

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

src/Count.vue






6.4 四个map方法的使用

  1. mapState方法:用于帮助映射state中的数据为计算属性
import {mapState} from 'vuex'
computed: {
  	// 借助mapState生成计算属性:sum、school、subject(对象写法一)
  	...mapState({sum:'sum',school:'school',subject:'subject'}),

  	// 借助mapState生成计算属性:sum、school、subject(数组写法二)
  	...mapState(['sum','school','subject']),
},
  1. mapGetters方法:用于帮助映射getters中的数据为计算属性
import {mapGetters} from 'vuex'
computed: {
    //借助mapGetters生成计算属性:bigSum(对象写法一)
    ...mapGetters({bigSum:'bigSum'}),

    //借助mapGetters生成计算属性:bigSum(数组写法二)
    ...mapGetters(['bigSum'])
},
  1. mapActions方法:用于帮助生成与actions对话的方法,即包含$store.dispatch(xxx)的函数
import {mapActions} from 'vuex'
methods: {
    // 靠mapActions生成:addOdd,addWait(对象形式)
    ...mapActions({incrementOdd: 'addOdd', incrementWait: 'addWait'}),
    // 靠mapActions生成:addOdd,addWait(数组形式)
    // ...mapActions(['addOdd', 'addWait'])
},
  1. mapMutations方法:用于帮助生成与mutations对话的方法,即包含$store.commit(xxx)的函数
import {mapMutations} from 'vuex'
methods: {
    // 靠mapMutations生成:increment,decrement(对象形式)
    ...mapMutations({increment: "ADD", decrement: "SUB"}),
    // 靠mapMutations生成:ADD,SUB(数组形式)前提是click函数名也为ADD和SUB
    // ...mapMutations(['ADD', 'SUB']),
},

注意mapActionsmapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象

src/components/Count.vue






6.5 多组件共享数据案例

src/App.vue




src/store/index.js 该文件用于创建Vuex中最为核心的store

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

Vue.use(Vuex);

const actions = {
    addOdd(context, value) {
        if (context.state.sum % 2) context.commit("ADD", value);
    },
    addWait(context, value) {
        setTimeout(() => {
            context.commit("ADD", value)
        }, 500)
    }
}

const mutations = {
    ADD(state, value) {
        state.sum += value;
    },
    SUB(state, value) {
        state.sum -= value;
    },
    ADD_PERSON(state, value) {
        state.personList.unshift(value);
    }
}

const state = {
    sum: 0,
    school: 'CQJTU',
    subject: 'Java',
    personList: []
}

// 准备getters对象---用于将state中的数据进行加工
const getters = {
    bigSum() {
        return state.sum * 10;
    }
}

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

src/components/Count.vue






src/components/Person.vue




Vue2&3全面知识总结六_第7张图片

6.6 模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确

  2. 修改store.js

    为了解决不同模块命名冲突的问题,将不同模块的namespaced: true,之后在不同页面中引入getter actions mutations时,需要加上所属的模块名

const countAbout = {
  namespaced: true,	// 开启命名空间
  state: {x:1},
  mutations: { ... },
  actions: { ... },
  getters: {
    bigSum(state){ return state.sum * 10 }
  }
}

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

const store = new Vuex.Store({
  modules: {
    countAbout,
    personAbout
  }
})
  1. 开启命名空间后,组件中读取state数据
// 方式一:自己直接读取
this.$store.state.personAbout.list
// 方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),
  1. 开启命名空间后,组件中读取getters数据
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])
  1. 开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'addOdd',incrementWait:'addWait'})
  1. 开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'ADD',decrement:'SUB'}),

多组件共享数据案例修改

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import countOptions from './count'		// 引入count
import personOptions from './person'	// 引入person

Vue.use(Vuex)
   
//创建并暴露store
export default new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions,
    }
})

src/store/count.js

export default {
    // 开启命名空间
    namespaced: true,
    actions: {
        addOdd(context, value) {
            if (context.state.sum % 2) context.commit("ADD", value);
        },  
        addWait(context, value) {
            setTimeout(() => {
                context.commit("ADD", value)
            }, 500)
        }
    },
    mutations: {
        ADD(state, value) {
            state.sum += value;
        },
        SUB(state, value) {
            state.sum -= value;
        },
    },
    state: {
        sum: 0,
        school: 'CQJTU',
        subject: 'Java',
    },
    getters: {
        bigSum(state) {
            return state.sum * 10;
        }
    }
}

src/store/person.js

import axios from "axios";
import {nanoid} from "nanoid";

export default {
    namespaced: true,
    actions: {
        addPersonLi(context, value) {
            if (value.name.indexOf("李") === 0) {
                context.commit("ADD_PERSON", value)
            } else {
                alert("添加的人必须姓李!")
            }
        },
        addPersonServer(context) {
            axios.get('http://api.uixsj.cn/hitokoto/get?type=social').then(
                response => {
                    context.commit("ADD_PERSON", {id: nanoid(), name: response.data})
                },
                error => {
                    alert(error.message)
                }
            )
        }
    },
    mutations: {
        ADD_PERSON(state, value) {
            state.personList.unshift(value);
        }
    },
    state: {
        personList: [{
            id: '001',
            name: "张三",
        }]
    },
    getters: {
        firstPersonName(state) {
            return state.personList[0].name
        }
    }
}

src/components/Count.vue






src/components/Person.vue




Vue2&3全面知识总结六_第8张图片

你可能感兴趣的:(前端,vue.js,javascript,前端,前端框架)