vue的全局状态管理器
实现组件之间跨层传递数据
实现数据与视图响应式更新
state
geeters
mutations
actions
modules
namespaced
----命名空间
state
$store.state.数据名字
// 数据
state: {
// 这个数据写死了
goods : [{"buy_limit":5,"img_url":"\/\/i8.mifile.cn\/v1\/a1\/ef617fac-7489-436d-b74e-c43582f09633.jpg","num":1,"price":899,"name":"\u5c0f\u7c73\u7535\u89c64A 32\u82f1\u5bf8","goods_id":2172700021,"select":true},{"buy_limit":1,"img_url":"\/\/i8.mifile.cn\/v1\/a1\/65be1bac-6d3f-3766-3bac-c11b3aa13b8e.webp","num":1,"price":1199,"name":"Redmi Note 7 4GB+64GB \u68a6\u5e7b\u84dd","goods_id":2185200032,"select":true},{"buy_limit":5,"img_url":"\/\/i8.mifile.cn\/a1\/pms_1514387870.88251945.jpg","num":1,"price":3599,"name":"\u5c0f\u7c73\u7b14\u8bb0\u672cAir 12.5 4G 128G \u94f6\u8272","goods_id":2175200001,"select":true}]
}
<div class="good" v-for="good in $store.state.goods" :key="good.goods_id">
geeters
- `getters 从现有数据获取到新的数据`,相当于vue组件中的`computed`
- `名字 : state => { 逻辑。。。 ; return 数据}`
- 在vue组件中获取:`$store.gettes.数据名字`
// 使用
getters : {
goodNum : state => {
let num = 0;
state.goods.forEach( item => {
num += item.num;
})
return num;
}
},
<van-tabbar-item to="/cart" icon="setting-o" :badge="$store.getters.goodNum">
mutations
mutations
方法,操作数据,相当于vue组件中的methods
$store.commit("传过来的事件名字",需要传递的参数);
// 使用
mutations: {
// delGood事件名字,(state,good),state:对应state中的数据,good:对应组件传递过来的参数
delGoodVuex(state,good) {
var flag = window.confirm("你确定要删除码?");
if(flag) {
var index = state.goods.indexOf(good);
state.goods.splice(index,1);
}
},
// 调用
// delGood 是vue中的事件,
delGood() {
// this.$store.commit 就是接收,vuex中的事件delGoodVuex,且传递参数this.good.num,
this.$store.commit("delGoodVuex",this.good.num);
},
actions
关于Ajax异步的方法需要放在actions
中,执行异步的方法
actions 方法,可以执行异步操作方法,相当于vue组件中的methods
在vue组件中使用:$store.dispatch("方法名字",data);
使用:方法名字({commit},[参数]) { ajax方法};
actions: {
// 解构mutations中的所有方法
getCart({commit}) {
getCartAPI()
.then( res => {
// 已经结构了vuex中的mutations中的方法,
// 所以调用初始化购物车的方法只需要:commit("方法名字",需要传输过来的数据);
// 这里是因为调用了vuex本身的事件方法,所以使用此写法
// 因为commit 是已经解构的方法,所以只需正确的找到需要的方法就行了,如果传参,就写参数
commit("INIT_CART",res.data);
})
.catch( err => {
console.log(err);
})
}
},
mutations : {
// 初始化购物车的方法
INIT_CART(state,goods) {
state.goods = goods;
}
}
$store.dispatch("方法名字");
// 调用actions的方法
// 在vue中调用vuex的actions中的方法
this.$store.dispatch("getCart");
modules
state
,mutations
,actions
,getters
login.js
// 登录模块的state
const state = {}
// 登录模块的getters
const getters = {}
// 登录模块的mutations
const mutations = {}
// 登录模块的actions
const actions = {}
// 导出默认的模块方法
export default {state,getters,mutations,actions}
// 导入 login模块
import login from './modules/Login.js'
// 注册到vuex中
modules : {
login
}
$store.state.注册的模块名.参数等
// 使用,存储数据
const state = {
name : "momo",
age : 20
}
<p>获取vuex中的模块数据 {{$store.state.login.name}}----{{$store.state.login.age}}p>
state 自己这个模块的state
getters 全局的getters,包括模块的getters
rootState 全局的state
// 使用
const getters = {
<!-- 参数1,参数2,参数3,参考以上 -->
getGoods(state,getters,rootState){
console.log(state,getters,rootState)
return getters.goodNum;
}
}
$store.getters.模块中的getters中的数据名字
<p>getter:{{$store.getters.getGoods}}p>
$store.commit("需要调用的模块中的方法名字",需要传递的参数)
// 使用
const mutations = {
ADD_AGE(state,step=1) {
state.age += step;
}
}
$store.commit("需要调用的模块中的方法名字",需要传递的参数)
<button @click="$store.commit('ADD_AGE')">年龄加button>
方法名字({context},[参数]) { 逻辑 }
// 使用
const actions = {
addAge(context,arg){
// 这个是调用上下文中定义mutations的ADD_AGE事件
context.commit("ADD_AGE",arg);
var good = {"buy_limit":5,"img_url":"\/\/i8.mifile.cn\/v1\/a1\/ef617fac-7489-436d-b74e-c43582f09633.jpg","num":2,"price":8990,"name":"小米55","goods_id":2172700028,"select":true};
console.log(context);
// 模块访问vuex中全局的方法
context.commit("addGood",good);
// 模块可以访问vuex全局的state
context.rootState.goods.pop();
}
}
$store.dispatch('需要调用的模块的actions方法')
<button @click="$store.dispatch('addAge')">actions年龄减button>
// 导出
export default {
// 命名空间
namespaced : true,
state,
getters,
mutations,
actions
}
数据名字(state,getters,rootState,rootGetters) {逻辑; return 数据}
$store.getters["模块名字/数据名字"];
...mapGetters["模块名字/数据名字"]
方法名字(state,参数);
$store.commit("模块名字/方法名字",需要传递的数据参数)
...mapMutations["模块名字/数据名字"]
this.commit("需要调用的方法")
那个组件使用那个vuex中的属性就导入对应的映射方法
映射方法对应:mapState
,mapGetters
,mapMutations
,mapActions
导入方法:import {对应的映射方法} from 'vuex';
使用方法:...对应的映射方法(['需要调用的vuex的方法,或者数据'])
原因:这样可以不用在写,$store.state.数据名
等这种
vuex中getters
映射成vue中的computed
就是对应的使用方法需要在对用映射成的vue的方法中才能使用
vuex中的actions
,映射成vue中的methds
需要使用时,就跟使用vue中的数据,方法一样
// 导入映射的vuex的方法
// vuex中getters 映射成vue中的computed
// vuex中的actions ,映射成vue中的methds
import {mapGetters,mapActions} from 'vuex';
import Bus from '@/utils/Bus.js';
export default{
data(){return {
isShow:true,
active : 0
}},
computed : {
...mapGetters(['goodNum'])
},
created(){
// 因为有了映射的方法,我们就不用再使用dispatch这种了
// this.$store.dispatch("getCart");
this.getCart();
},
methods : {
...mapActions(["getCart"])
}
}