目录
vuex中有三个模块:cart,address,restaurant
cart
state
cartList是个对象 里面存了restaurant_id商店id 也是个对象
32是商店id(restaurant_id),里面有食品id(food_id)、商店图片pic_url、商店名称restaurant_name、总数totalNum、总价totalPrice点开之后:
1087是食品id(food_id),里面包含食品图片foods_pic、食品名称name、食品数量num、食品价格price、食品编号id(和food_id的值一样,也就是说在food_id中还有一个id变量保存着食品id)。点开后:
mutation
ADD_CART将食物加入购物车
如果cartList中没有这个餐馆,初始化这个餐馆并添加进cartList中,如果cartList中有这个餐馆,则获取餐馆,再从餐馆中看有没有该食品,如果没有,初始化食品并添加进餐馆,如果有这个食品,食品数量+1,最后计算总价,总数量+1,更新cartList并保存在localStorage中
ADD_CART(state, {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) {
let cart = state.cartList;
let restaurant;
if (!cart[restaurant_id]) { //如果购物车中没有该商店 说明该商店还没有添加任何商品 进行初始化
restaurant = cart[restaurant_id] = {
totalPrice: 0, //总价格
totalNum: 0, //总数量
restaurant_name, //餐馆名
pic_url //餐馆图片
};
} else {
restaurant = cart[restaurant_id];// 从购物车中获取餐馆
}
if (restaurant[food_id]) { //如果该食物已经保存了 数量加1
restaurant[food_id].num++;
} else {
restaurant[food_id] = {// 该食物没保存 初始化该食物
name,// 食物名称
price,// 食物价格
foods_pic,// 食物图片
num: 1,// 数量
id: food_id,// 食物id
}
}
restaurant.totalPrice = (Number(restaurant.totalPrice) + Number(price)).toFixed(2); //计算该餐馆的总价格
restaurant.totalNum++; //该餐馆的食品总数量加一
state.cartList = {...cart}//触发更新
localStorage.setItem('cartList', JSON.stringify(state.cartList));// 通过localStorage将购物车cartList缓存在本地
},
REDUCE_CART购物车中的食品-1
从cartList中获取餐馆,食品的总价、总数量、食品的数量都相应-1,如果食品数量=0,从餐馆中删除该食品,如果餐馆的总数量=0,从cartList中删除该商店,更新cartList并保存在localStorage中
REDUCE_CART(state, {restaurant_id, food_id}) {
let cart = state.cartList;
let restaurant = cart[restaurant_id];// 从购物车中获取餐馆
restaurant.totalPrice = Number((restaurant.totalPrice - restaurant[food_id].price).toFixed(2));
restaurant.totalNum--;
restaurant[food_id].num--;
if (restaurant[food_id].num === 0) delete(restaurant[food_id]);
if (restaurant.totalNum === 0) delete(cart[restaurant_id]);
state.cartList = {...cart};
localStorage.setItem('cartList', JSON.stringify(state.cartList));
}
DELETE_CART从购物车中删除食品
从餐馆中的食品对象中获取该食品的数量和价格,从餐馆中获取餐馆的总食品数量和总价,餐馆新总食品数量 - 餐馆中该食品的总数,如果=0,从cartList中删除该餐馆,否则计算餐馆新的总价=总价-食品数量 * 食品总数,更新cartList并保存在localStorage中
DELETE_CART(state, {restaurant_id, food_id}) {
let cart = state.cartList;// 购物车
let restaurant = cart[restaurant_id];// 餐馆
let num = restaurant[food_id].num;// 餐馆中的该食品总数
let price = restaurant[food_id].price;// 餐馆中该食品的价格
restaurant.totalNum -= num;// 餐馆总食品数量 - 餐馆中该食品的总数
delete(restaurant[food_id]);// 删除餐馆中该食品
if (restaurant.totalNum === 0) {// 如果餐馆中食品数量为0 从购物车中删除该餐馆
delete(cart[restaurant_id]);
} else {//否则修改餐馆的总价格 = 餐馆的总价格 - 食品数量 * 食品总数
restaurant.totalPrice = Number((restaurant.totalPrice - price * num).toFixed(2));
}
state.cartList = {...cart};// 更改vuex中的购物车内容
localStorage.setItem('cartList', JSON.stringify(state.cartList));// 将购物车中的内容保存在localStorage中
}
UPDATE_CART更新购物车
UPDATE_CART(state, {cartList}) {
state.cartList = {...cartList};
}
EMPTY_CART清空购物车
删除购物车中该商店的数据。清空购物车只能一个商店一个商店清
EMPTY_CART(state, {restaurant_id}) {
let cart = state.cartList;
delete cart[restaurant_id];// 删除购物车中该商店的数据
state.cartList = {...cart};
localStorage.setItem('cartList', JSON.stringify(state.cartList));// 将新的购物车的数据重新保存在localStorage中
},
address
state
保存了定位信息、定位是否完成标志位、收货地址
state = {
address: {// 定位信息
address: '定位中...',
lat: '',
lng: '',
},
locationReady: false, //定位是否完成
deliveryAddress: {}
};
actions
保存了一个定位方法,定位方法调用后端location接口,后端location接口先后调用了两个方法,一个是获取经纬度的getLocation(),一个是获取省市信息的getDetailPosition()。
- getLocation():后端向
ip.cn
发送get请求,获取IP,带着IP和腾讯位置服务的密钥向腾讯位置服务/api/index接口发送get请求,将获取到的经纬度保存在cityInfo,返回cityInfo - getDetailPosition():后端带着上一个方法返回的cityInfo继续执行getDetailPosition(),根据经纬度获取详细地址信息:带着经纬度和腾讯位置服务的密钥向腾讯位置服务/geocoder/v1接口发送get请求,从返回信息中截取省、市信息和经纬度保存在一起(保存为一个对象)并返回给前端
前端得到数据后调用mutations的RECORD_ADDRESS()保存地址,调用LOCATION_READY()设置标志位,标识定位完成,可以拉取商店。
location({commit}) {
location().then((response) => {//异步 location方法来源于api中的location方法
if (response.data.status === 200) {//200表示地址获取成功
let data = response.data.data;//取得数据
//调用了给地址重新赋值的方法types.RECORD_ADDRESS 把拿到的data数据中的address和location赋值给address
commit(types.RECORD_ADDRESS, {address: data.address, ...data.location}); //保存title 和 经纬度到VUEX中
commit(types.LOCATION_READY, true);//定位完成 拉取商店
}
})
},
location = (data) =>{
let req = {data}
req.url = 'v1/location'
return _get(req)
}
mutations
const mutations = {
[types.CLEAR_ADDRESS](state) {// 清除地址
let address = {address: '定位中...', lat: '', lng: ''};
state.address = {...address};
},
[types.RECORD_ADDRESS](state, address) {// 保存地址
state.address = {...address}
},
//定位完成拉取附近餐馆
[types.LOCATION_READY](state, boolean) {// 设置标志位,标识定位完成,可以拉取商店。
state.locationReady = boolean;
},
[types.RECORD_DELIVERY_ADDRESS](state, address) {// 保存收货地址
state.deliveryAddress = {...address};
},
[types.FAIL_LOCATION](state) {// 定位失败时,地址为默认值,也就是没有地址,清空地址
let address = {address: '定位失败...', lat: '', lng: ''}
state.address = {...address};
}
};
restaurant
state
存放了一个poi_info对象,用于保存当前商店的数据,内容如下:
discounts2是个数组 数组中的内容:
actions
保存了一个获取指定餐馆信息的方法,该方法调用后端getRestaurant接口,该接口拿着餐馆id去数据库中查询,将查询到的数据返回给前端。前端调用mutations中的方法保存餐馆信息
const actions = {
getRestaurant({commit}, restaurant_id) {
getRestaurant({restaurant_id}).then((response) => {
// 带着餐馆id调用后端接口,后端拿着餐馆id去数据库中查询,将查询到的数据返回给前端
let poi_info = response.data.data;
commit('RECORD_RESTAURANT', poi_info)// 调用mutations中的方法保存餐馆信息
})
}
};
//获取某个商家具体信息
export const getRestaurant = (data) => {
let req = {url: `v1/restaurant/${data.restaurant_id}`};
return _get(req);
}
mutations
const mutations = {
//记录当前商店的信息
[types.RECORD_RESTAURANT](state, poi_info) {
state.poi_info = {...poi_info}
},
};