vuex
- vue的全局状态管理器
- 实现组件之间跨层传递数据实现数据与视图响应更新
- 需要多个组件使用的数据或方法放到vuex中
state 状态数据
- 存放数据的地方 相当于data 在组件中获取$store.state.xxx
- 在组件computed属性中通过…mapState([xxx,yyy])获取
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}]
},
使用
// mapState 把vuex 里面的state 值映射为vue里面computed 属性
import{ mapState} from 'vuex'
computed:{
...mapState(["goods"])
},
getters
- 从现有数据计算出新数据,相当于vue的computed 使用$store.getter.xxx
- 在组件computed属性中通过…mapGetters([xxx,yyy])
例:获取商品总数量
getters:{
goodNum:state=>{
let num=0;
state.goods.forEach(item=>num+=item.num)
return num
}
},
mutations
- 操作数据 相当于methods 组件中使用 $store.commit(“delGood”,data)
- 在组件的methods 属性中通过…mapMutations([xxx,yyy])获取
删除商品
mutations: {
delGood(state,good){
var index=state.goods.indexOf(good)
state.goods.splice(index,1)
}
},
组件中使用
<div class="col-10 bottom">
<van-icon name="delete" @click="$store.commit('delGood',good)" />
</div>
新增商品
addGood(state,good){
//如果商品在购物车中有 数量加1
//如果数量超过max数量 等于最大购买的数量
// 否则添加购物车
var flag=false;//默认没有
good.num?"":good.num=1;
good.select?"":good.select=true;
good.buy_limit?"":good.buy_limit=good.mulit_buy_limit
flag=state.goods.some(item=>{
if(item.goods_id==good.goods_id){
item.num=(item.num+1)*1;
if(item.num>item.buy_limit){
item.num=item.buy_limit
alert("最多买"+item.num+"件")
}
return true
}
})
if(!flag){
state.goods.unshift(good)
}
var temp=state.goods;
state.goods=[];
state.goods=temp
}
},
在组件中使用
@click="$store.commit('addGood',produce)"
或者
// mapMutation 把vuex里面的mutations方法映射为vue里面的methods 方法
import{ mapMutations} from 'vuex'
methods:{
...mapMutations(["UPDATE"," INIT_CART"])
}
//可以直接使用UPDATE
actions
- 可以执行异步操作方法,相当于组件中methods 在组件中使用this.$store.dispatch(“getCart”,data)
- 在 组件methods 中通过…mapActions([xxx,yyy])获取
mutations: {
INIT_CART(state,goods){
state.goods=goods
}
},
actions: {
getCart({commit}){
getCart()
.then(res=>{
commit("INIT_CART",res.data)
})
.catch(err=>console.log(err))
}
},
使用
created(){
this.$store.dispatch("getCart")
}
或者
import {mapGetters,mapActions} from 'vuex'
// 从vuex 里面导入一个映射Getters 映射方法Aticon 能把vuex里面的getter映射为 vue里面的 computed
// 能够把vuex里面的Action 映射为 vue里面的方法methods
methods:{
...mapActions(["getCart"])
//直接使用getCart
}
modules 模块
- vuex允许我们将store分割成模块
- 每一个模块都有
state mutations actions getters - state
默认带命名空间 $store.state.login.gae - commit 默认不带命名空间 $store.commit(xxx)
- actions 默认不带命名空间 $store.dispatch(xxx)
第一参数context 里面的内容
commit getters dispatch rootState 全局state rootGetters全局getters - getters 参数
- 参数1 state 模块的state
- 参数2 getters全局的getters
- 参数3 rootState全局的state
在sore文件夹下新建module文件夹,新建login.js 如下
const state = {
name:"hhh",
age:18
};
const mutations = {
ADD_AGE(state,step=1){
state.age+=step;
console.log(state)
}
}
const getters = {
getGoods(state,getters,rootState){
console.log(state,getters,rootState)
return getters.goodNum;
}
}
const actions = {
addAge(context,arg){
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);
context.commit("addGood",good);
context.rootState.goods.pop();
}
}
export default {state,mutations,actions,getters}
stroe文件夹的index.js文件中
//引入
import login from './modules/Login.js'
modules: {
login
},
命名空间
- namespaced:true
- getters
getGood(state,getters,rootState,rootGetters){
console.log(state,getters,rootState,rootGetters)
return rootGetters.goodNum;
}
使用
$stroe.getters["login/getGood"]
- mutations
ADD_AGE(state,step=1)
使用
$store.commit("login/ADD_AGE")
- actions
访问全局
context.commit("addGood",good,{root:true})
本地
context.commit("ADD_ADD_AGE")
把登录信息 获取的用户信息 退出登录放入vuex中
import {Login,Exit,getUser} from '../../api/user.js'//引入登录、退出、信息的api
import { Notify } from 'vant';//引入vant的Notify组件
import router from '@/router/index.js'//导入路由
const state={
user:{},
token:null
}
const getters={
}
const mutations={
setToken(state,val){
state.token=val;
sessionStorage.setItem("token",val)
},
setUser(state,val){
state.user=val;
}
}
const actions={
//定义一个动作方法 login
login({commit},data){//解析出commit 提交方法
Login(data)//导入api方法
.then(res=>{
if(res.data.status==1){
commit("setToken",res.data.token);// 提交commit
if(router.currentRoute.query.redirect){
// 如果路由的当前路由页面查询的redirect值有
// 跳转对应的页面 router.push(router.currentRoute.query.redirect)
}else{
router.push("/user")
}
Notify({type:"success",message:"登录成功"})
}else{Notify(res.data.msg) }
})
.catch(err=>{ Notify("登录失败");})
},
//获取用户信息
getUser({commit}){
getUser()
.then(res=>{
commit("setUser",res.data)
})
},
//退出登录
exit({commit}){
Exit()
.then(res=>{
if(res.data.status==1){
commit("setToken",{})
commit("setUser",{})
Notify({type:"success",message:"退出成功"});
}
})
}
}
export default {state,actions,mutations}
使用
登录页面
<button @click="$store.dispatch('login',user)">登录</button>
个人中心页面
<div v-if="user.M_ID">
{{user.M_UserName}}
<span @click="$store.dispatch('exit')">注销</span>
</div>
<div v-else>
<router-link to="/login">登录</router-link>|<router-link to="/register">注册</router-link>
</div>
created(){
if(!this.user.M_ID){
this.$store.dispatch("getUser")
}
},
// 组件创建完毕获取用户
computed:{
user:function(){return this.$store.state.login.user}
},
退出
<span @click="$store.dispatch('exit')">注销</span>