5.vuex使用
5.1 理解vuex
5.1.1 vuex定义
(1)概念:专门在Vue中实现集中式状态(也叫:数据、状态数据,之后统称:状态)管理的VUe插件,对vue应用中多个组件共享状态进行集中式的管理(读/写),也是一种组件通信的方式,适用于任何组件。
(2)地址:GitHub - vuejs/vuex: 🗃️ Centralized State Management for Vue.js.
当某个属性,所有组件都需要使用:
5.1.2 使用场景:
(1)当多个组件依赖同一个状态。
(2)来自不同组件的行为要变更同一个状态。
5.2 搭建vuex环境
(1)创建 文件夹:src/store/index.js
//该文件用于vuex中最为核心的store //引入Vue import Vue from 'vue' //引入vuex import Vuex from 'vuex' //准备actions 用于响应组件里的动作 const actions = { } //准备mutations 用于真正操作state中的数据 const mutations = { } //准备state 用于存储数据 const state = { } Vue.use(Vuex) //创建并暴露store export default new Vuex.Store({ actions, mutations, state, })
(2)在main.js中创建vm时传入store:
import store from './store' const vm=new Vue({ el:"#app", render:h=>h(App), store, beforeCreate(){ Vue.prototype.$bus=this } })
(3)注意:必须在index.js中引入Vue并使用插件vuex,否则new Vuex.Store()会报错。
5.3 基本使用
(1)初始化数据(state),配置actions,配置mutations,操作文件store.js。
//该文件用于vuex中最为核心的store //引入Vue import Vue from 'vue' //引入vuex import Vuex from 'vuex' //准备actions 用于响应组件里的动作 const actions = { /* add(context,value){ // console.log("store.actions.add,context=",context,"value=",value) context.commit("ADD",value) }, sub(context,value){ context.commit("SUB",value) }, */isOdd(context, value) { console.log("store.actions.isOdd",value) context.dispatch("demo1", value) }, demo1(context, value) { console.log("store.actions.demo1",value) context.dispatch("demo2", value) }, demo2(context, value) { console.log("store.actions.demo2") if (context.state.sum % 2 != 0) { console.log("store.actions.isOdd") context.commit("ADD", value) } }, sleepAdd(context, value) { console.log("store.actions.sleepAdd") setTimeout(() => { context.commit("ADD", value) }, 1000); } } //准备mutations 用于真正操作state中的数据 const mutations = { ADD(state, value) { // console.log("store.mutations.ADD,state=",state,"value=",value) console.log("store.mutations.ADD") state.sum += value }, SUB(state, value) { console.log("store.mutations.state") // console.log("store.mutations.ADD,state=",state,"value=",value) state.sum -= value } } //准备state 用于存储数据 const state = { sum: 0, } Vue.use(Vuex) //创建并暴露store export default new Vuex.Store({ actions, mutations, state, })
(2)组件读取vuex中的数据:$taore.state.sum
(3)修改vuex中的数据:$store.dispatch('action中的方法名',参数)或者$store.commit('mutations中的方法名',参数)。
<template> <div> <h1>当前求和为:{{ $store.state.sum }}</h1> <div class="sum"> <select v-model.number="n"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button @click="add">+</button> <button @click="sub">-</button> <button @click="isOdd">为奇数执行+</button> <button @click="sleepAdd">sleep后+</button> </div> </div> </template> <script> export default { props: {}, data() { return { n: 1, }; }, computed: {}, watch: {}, created() {}, mounted() {}, methods: { add() { // this.$store.dispatch("add", this.n); this.$store.commit("ADD",this.n) }, sub() { // this.$store.dispatch("sub", this.n); this.$store.commit("SUB",this.n) }, isOdd() { /* if (this.sum % 2 != 0) { this.add(); } */ this.$store.dispatch("isOdd", this.n); }, sleepAdd() { this.$store.dispatch("sleepAdd", this.n); }, }, }; </script> <style scoped lang="less"> .sum { select, button { font-size: 20px; min-width: 50px; } } </style>
备注:若没有网络请求或者其他业务逻辑,组件们可以越过actions直接访问mutations中的方法,既直接写commit()。
5.4 getters的使用
(1)概念:当state中的数据需要加工后在使用时,可以使用getters参数。
(2)配置getters属性:
//将state中的数据进行加工 const getters={ bigSum(state){ return state.sum*10 } } //创建并暴露store export default new Vuex.Store({ actions, mutations, state, getters })
(3)组件中读取数据:$store.getters.bigSum。
5.5 四个map方法
5.5.1 mapState方法:
用于帮助我们映射state中的数据为计算属性:
computed:{ //借助mapState生成计算属性,从state中读取数据(对象写法) // ...mapState({school:'school',subject:'subject',sum:'sum'}) // 数组写法 ...mapState(['school','subject','sum']), }
5.5.2 mapGetters方法:
用于帮助我们映射getters中的数据为计算属性
computed:{ //借助mapState生成计算属性,从state中读取数据(对象写法) // ...mapGetters({bigSum:'bigSum'}) // 数组写法 ...mapGetters(['bigSum']), }
5.2.3 mapActions方法
用于帮助我们生成与actions对话的方法,既:包含$store.dispatch(xxx)的函数。
//对象式 // ...mapActions({sleepAdd:'sleepAdd',isOdd:'isOdd'}) //数组式 ...mapActions(['sleepAdd','isOdd'])
5.2.4 mapMutations方法
用于帮助我们生成与mutations对话的方法,既:包含$store.commit(xxx)的函数。
//对象式 // ...mapMutations({add:'ADD',sub:'SUB'}), //数组式 ...mapMutations(['ADD','SUB']),
5.2.5 注意
mapActions与mapMutations使用时,若需要参数,应在模板绑定事件时传递参数,否则参数是事件对象。
5.6 模块化+命名空间
(1)目的:让代码更好维护,多种数据分类更加明确。
(2)修改store.js,拆分为两个:person.js,count.js
person.js
//人员功能相关的 export default { namespaced:true, actions: { addPerson(context, value) { console.log("store.actions.addPerson") if (value != "") { context.commit("ADDPERSON", value) } else { alert("请输入姓名") } } }, mutations: { ADDPERSON(state, value) { state.personList.push(value) } }, state: { personList: ['张三'] }, getters: {} }
conut.js
//求和功能相关的 export default { namespaced:true, actions: { isOdd(context, value) { console.log("store.actions.isOdd", value) if (context.state.sum % 2 != 0) { console.log("store.actions.isOdd") context.commit("ADD", value) } }, sleepAdd(context, value) { console.log("store.actions.sleepAdd") setTimeout(() => { context.commit("ADD", value) }, 1000); }, }, mutations: { ADD(state, value) { // console.log("store.mutations.ADD,state=",state,"value=",value) console.log("store.mutations.ADD") state.sum += value }, SUB(state, value) { console.log("store.mutations.state") // console.log("store.mutations.ADD,state=",state,"value=",value) state.sum -= value }, }, state: { sum: 0, }, getters: { bigSum(state) { return state.sum * 10 } } }
index.js
//该文件用于vuex中最为核心的store //引入Vue import Vue from 'vue' //引入vuex import Vuex from 'vuex' import sumOptions from './count' import personOptions from './person' Vue.use(Vuex) //创建并暴露store export default new Vuex.Store({ modules:{ coundAbout:sumOptions, personAbout:personOptions, } })
(3)namespaced:true开启命名空间。
(4)开启命名空间后组件,读取state中的数据:
//方式1 直接读取 this.$store.state.personAbout.personList //方式2 借助mapState读取 ...mapState('countAbout',[sum])
(4)开启命名空间后,组件读取getters中的数据:
//方式1 直接读取 this.$store.getters['personAbout/firstName'] //方式2 借助mapGetters读取 ...mapState('countAbout',['bigSum'])
(5)开启命名空间后,组件调用dispatch:
//方式1 直接调用dispatch this.$store.dispatch('personAbout/addPerson',{name:'王'}) //方式2 借助mapActions读取 ...mapActions('countAbout',['isOdd','sleepAdd'])
(6)开启命名空间后,组件调用commit:
//方式1 直接调用commit this.$store.commit('personAbout/ADD_PERSON',{name:'王'}) //方式2 借助mapMutations读取 ...mapMutations('countAbout',['ADD','SUB'])