文章目录
Vuex
1.概念
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
2.何时使用?
多个组件需要共享数据时
组件中读取vuex中的数据:$store.state.sum
组件中修改vuex中的数据:$store.dispatch(‘action中的方法名’,数据)或 $store.commit(‘mutations中的方法名’,数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit
过程
-
在需要用数据的组件(vuecomponents)里 在函数里this.$store.dispatch 转交给actions
-
action是个对象 对象里有很多函数(放入dispatch接受的函数)
函数的参数为(miniStore(context),value)
context实际就是有commit和dispatch,state功能的迷你store 因为让你用commit走mutations
用state里的数据让你判断条件是否commit
可以ajax 可以异步定时器 -
action的函数commit后 转为大写的函数 进入mutations
有两个参数 (sate,value) 进行真正的函数操作 将state匹配了getter setter -
state 数据 对象类型
vue component 组件
dispatch 函数 接受函数 和value
actions 对象里有很多函数(放入dispatch接受的函数)
1. 搭建环境
在main.js中
//引入store 并已经成为全局use
import store from './store/index'
---
new Vue({
el:'#app',
render: h => h(App),
store,
beforeCreate() {
Vue.prototype.$bus = this
}
})
在src/store/index.js中
import Vue from 'vue'
import Vuex from 'vuex'
//只要use了 vm和vc就有tore 不用放在原型上 因为它是插件可以全局使用
Vue.use(Vuex)
//创建vuex的store
//用于响应组件中的动作
const actions={
}
//准备 mutations 用于操作数据(state)
const mutations={}
//准备state 存储数据
const state={}
// 创建store导出 它本质是一个对象里面有action state mutations
export default new Vuex.store({
actions,
state,
mutations,
})
进行调用
在需要数据的组件中
methods: {
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)
},
},
在store中
const actions = {
/* jia(context,value){
console.log('actions中的jia被调用了')
context.commit('JIA',value)
},
jian(context,value){
console.log('actions中的jian被调用了')
context.commit('JIAN',value)
}, */
jiaOdd(context,value){
console.log('actions中的jiaOdd被调用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被调用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
}
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state,value){
console.log('mutations中的JIA被调用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被调用了')
state.sum -= value
}
}
//准备state——用于存储数据
const state = {
sum:0 //当前的和
}
注意
-
如果在active里没有操作 只是单纯的转发 可以直接在组件中this.$store.commit
-
可以在actions里面 再context.dispatch(‘demo’,value)
demo里面 commit 也就是业务逻辑比较复杂再调用一个函数 -
如果在actions里 因为能用context直接拿到state 直接写函数 这样开发者工具vuex会失效 因为它是跟mutations对话
5.getters的使用
用于store
概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
在store.js中追加getters配置
注意格式 getters也是对象 里面是函数
函数的参数是state 函数返回一个新的值 放在getters里面
直接写return
类似于计算属性的return 一个新的值
......
const getters = {
bigSum(state){
return state.sum * 10
}
}
//创建并暴露store
export default new Vuex.Store({
......
getters
})
组件中读取数据:$store.getters.bigSum
四个map方法的使用
用于原本组件 不用于store
先引入
import {mapState,mapGetters} from 'vuex'
在模板中使用$store.state.sum
$store.state.school
s
t
o
r
e
.
s
t
a
t
e
.
s
u
b
j
e
c
t
会
很
麻
烦
=
=
所
以
用
计
算
属
性
让
s
u
m
代
表
store.state.subject 会很麻烦 ==所以用计算属性 让sum代表
store.state.subject会很麻烦==所以用计算属性让sum代表store.state.sum==
mapState方法:用于帮助我们映射state中的数据为计算属性
表示的意思是 计算属性名为sum 去找state中的sum 依次映射
然后用…扩展运算符拆开 都赋值给了computed
也可以用数组的写法
表示一个 sum两种用途 一个是计算属性的名字 一个是state的结尾
computed: {
//借助mapState生成计算属性:sum、school、subject(对象写法)
...mapState({sum:'sum',school:'school',subject:'subject'}),
//借助mapState生成计算属性:sum、school、subject(数组写法)
...mapState(['sum','school','subject']),
},
mapGetters方法:用于帮助我们映射getters中的数据为计算属性
computed: {
//借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'}),
//借助mapGetters生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
},
mapActions方法
如果遇到这种情况 this. s t o r e . d i s p a t c h 和 t h i s . n 也 会 重 复 = = 用 m a p A c t i o n s 用 于 包 含 store.dispatch和this.n也会重复 ==用mapActions 用于包含 store.dispatch和this.n也会重复==用mapActions用于包含store.dispatch(xxx)的函数==
incrementOdd(){
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
this.$store.dispatch('jiaWait',this.n)
},
自己组件的函数名和 vuex的函数名映射 注意因为.dispatch的参数还有一个value(this.n) 所以value要写在模板里(调用这个函数的地方)
<button @click="incrementOdd(n)">当前求和为奇数再加</button>
<button @click="incrementWait(n)">等一等再加</button>
methods:{
//靠mapActions生成:incrementOdd、incrementWait(对象形式)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//靠mapActions生成:incrementOdd、incrementWait(数组形式)
...mapActions(['jiaOdd','jiaWait'])
}
mapMutations方法:
用于包含$store.commit(xxx)的函数
methods:{
//靠mapActions生成:increment、decrement(对象形式)
...mapMutations({increment:'JIA',decrement:'JIAN'}),
//靠mapMutations生成:JIA、JIAN(对象形式)
...mapMutations(['JIA','JIAN']),
}
用mapState 很轻松就可以两个组件之间传数据
computed:{
...mapState(['personList','sum']),
},
sum在store中 也是第一个组件的数据
但是第二个组件在 mapstate里之间引用 name就可以直接使用
模块化+命名空间
目的:让代码更好维护,让多种数据分类更加明确。
修改store.js
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
}
})
modeles是模块化的意思 一旦用了这个就代表store中的数据分类
开启命名空间后,组件中读取state数据:
personAbout在state里
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),
开启命名空间后,组件中读取getters数据:
要用personAbout/firstPersonName
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])
开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),