一、理解vuex
1.1 vuex是什么
1.1.1 概念:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
1.1.2 Github地址:
(https://github.com/vuejs/vuex)
1.2 什么时候用Vuex
Vuex本身会稍微繁琐复杂一点,对于相对大型项目来说使用Vuex的集中状态管理提供了极大的便利。如果项目比较简单,最好不要使用 Vuex。一个简单的 store 模式 就足够了。
1.3 Vuex的工作原理图
下图为Vue官网的Vuex工作流程图
整个过程可以理解为生活中的餐厅:VueComponents相当于去餐厅吃饭的客人,Actions相当于服务员,Mutations相当于餐厅的厨师,State相当于给客人上的饭菜,可以这么来理解。
Vuecomponents吆喝一句:“蛋炒饭不要加蛋!”
然后Actions:“好嘞,1号桌蛋炒饭不加蛋1份!”
后厨Mutations嘎啦嘎啦开始做餐。
Vuecomponents吃上了自个点的已经做好的餐State。
但是,总有与厨师比较熟的老朋友,一进来就可以不用找客服,吆喝一句厨房的厨师:“还是老样子!”
正常情况下是没问题的,但是餐厅为了满足不同客人的需求,会不定期的更换菜单,这会老熟人也不一定知道要吃啥,就得通过服务员提供的新菜单,这里的新菜单可以理解为Backend API,另一台服务器。(所以这里的Actions有时也可以省略,得看情况)
此外,需要注意的是:
Actions、Mutations、State。这三个的数据类型都为对象,其中dispatch和commit的方法都有store所提供。
需要通过store(仓库)来管理。这在图中没有具体表现,就像买车需要去车管所挂牌,这是必要的。
1.4 搭建Vuex环境
1.4.1 安装Vuex包
这里要注意的是,在2022.2.7,vue3成为了默认版本。在vuex3成为默认版本的同时,vuex也更新到了4版本,如果直接通过 npm i vuex 安装,会默认安装4版本,而vuex4只能在vue3中使用,如果在vue2项目中安装vuex4,就会出现冲突报错。
简言之:在vue2项目中,vuex使用3版本,在vue3项目中,vuex使用4版本。
npm i vuex@3
1.4.2 引入并使用vuex
//引入Vuex
import Vuex from 'vuex'
//使用Vuex
Vue.use(Vuex)
1.5 创建store文件夹
1.5.1 在store中创建index.js文件
(1) 在index.js中导入并引入Vue、Vuex并使用
// 引入Vue
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 使用 Vuex 插件
Vue.use(Vuex)
(2) 分别定义actions、mutations以及state
// 准备 actions 用于响应组件中的动作
const actions = {}
// 准备 muttations 用于操作数据
const muttations = {}
// 准备state 用于存储数据
const state = {}
1.5.2 创建并暴露store
// 创建并暴露 store
export default new Vuex.Store({
actions,
mutations,
state,
})
1.6 store的具体应用
1.6.1 没有特殊业务逻辑的可以直接在响应的vue文件的methods方法中配置具体方法,这里相当于是来餐厅吃饭的老熟人,可以跳过actions过程。
methods: {
// 在求和案例中分别配置加和减方法,这里可以直接用$store.commit方法
increment(){
this.$store.commit('JIA',this.n)
},
decrement(){
this.$store.commit('JIAN',this.n)
},
// 配置奇数时再加和等一等再加
incrementOdd(){
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
this.$store.dispatch('jiaWait',this.n)
},
}
1.6.2 另外,奇数时再加和等一等再加还需在store中通过actions设置条件
const actions = {
// 奇数时再加
jiaOdd:function(context,value){
console.log('actions中的jiaOdd被调用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
}
1.6.3 这里的context本意为上下文,可以理解为store的小老弟,具有store的部分属性和方法,详见下图分别为store和context具体方法。
1.7 getters的使用
(1)概念:
当state中的数据需要经过加工再使用时,可以使用getters加工。
(2)在store中的index.js文件中追加getters配置
//准备 getters 用于将state中的数据进行加工
const getters = {
bigSum(state){
return state.sum*10
}
}
// 创建并暴露 store
export default new Vuex.Store({
actions,
mutations,
state,
getters, //追加getters配置
})
(3)读取组件中的数据
在我们求和案例中,追加的配置为获取当前求和放大10倍的值,可以这样获取。
$store.getters.bigSum
1.8 Vuex的四个辅助函数
1.8.1 mapState
先引入mapState
import {mapState} from 'vuex'
// 原先写法
computed: {
sum(){
return this.$store.state.sum
},
school(){
return this.$store.state.school
},
subject(){
return this.$store.state.subject
},
}
computed: {
//借助mapState生成计算属性,从state中读取数据。(对象写法)
// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
// 通过mapState辅助函数生成计算属性,从state中读取数据(数组写法)
...mapState(['sum','school','subject']), //使用此方法的条件是生成计算属性名和读取的数据名是一致的
}
1.8.2 mapGetters
引入mapGetters
import {mapGetters} from 'vuex'
// 原先写法
computed: {
bigSum(){
return this.$store.getters.bigSum
},
}
computed: {
//借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
// ...mapGetters({bigSum:'bigSum'})
// 通过mapGetters辅助函数生成计算属性,从getters中读取数据(数组写法)
...mapGetters(['bigSum'])
}
1.8.3 mapMutations
引入mapMutations
import {mapMutations} from 'vuex'
//程序员亲自写方法
/* increment(){
this.$store.commit('JIA',this.n)
},
decrement(){
this.$store.commit('JIAN',this.n)
}, */
//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法) //...mapMutations({increment:'JIA',decrement:'JIAN'}),
//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
...mapMutations(['JIA','JIAN']),
1.8.4 mapActions
引入mapActions
import {mapActions} from 'vuex'
//程序员亲自写方法
/* incrementOdd(){
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
this.$store.dispatch('jiaWait',this.n)
}, */
//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法) //...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
...mapActions(['jiaOdd','jiaWait'])