1 ZOOM放大镜展示数据
放大镜和轮播图都是detail
的子组件
数据在仓库中了—skuInfo
–父给子—detail
给zoom
传数据—props
//1 详情页中 父亲给了
<ZoomYu :skuImageList="skuInfo.skuImageList"/>
//2 儿子收数据
props:['skuImageList']
//3 子组件展示数据
<img :src="skuImageList[0].imgUrl" />
//第一步中 直接给会报错 有可能是undefined
//这样写,确保至少是一个空数组,可以点;undefined不能点
//给子组件的数据
skuImageList() {
//如果服务器数据没有回来,skuInfo这个对象是空对象
return this.skuInfo.skuImageList || [];
},
<ZoomYu :skuImageList="skuImageList" />
//如果是空数组,数组的第0项。还是undefined,所以在子组件中再处理
//子组件中也要
computed:{
imgObj(){
return this.skuImageList[0]||{}
}
}
<img :src="imgObj.imgUrl" />
数据在仓库中了—skuInfo
–父给子—detail
给imageList
传数据—props
//1 父给子传数据
<ImageList :skuImageList="skuImageList" />
//2 接收
props:['skuImageList']
产品售卖属性数据的展示
//store中 先简化数据
spuSaleAttrList(state){
return state.goodInfo.spuSaleAttrList||[]
}
//简化完 详情页中捞数据
...mapGetters(["categoryView", "skuInfo", "spuSaleAttrList"]),
// 详情页中展示
<dl v-for="spuSaleAttr in spuSaleAttrList" :key="spuSaleAttr.id">
<dt class="title">{{ spuSaleAttr.saleAttrName }}</dt>
<dd
changepirce="0"
:class="{ active: spuSaleAttrValue.isChecked == 1 }"
v-for="attrValue in spuSaleAttr.spuSaleAttrValueList"
:key="attrValue.id"
>
{{ attrValue.saleAttrValueName }}
</dd>
</dl>
动态展示—排他
//绑定单机事件
methods: {
//售卖属性值切换高亮
changeActive(attrValue, arr) {
//排他 遍历售卖属性值全部为0 不高亮
arr.forEach((item) => {
item.isChecked = 0;
});
//点击的那个售卖属性值
saleAttrValue.isChecked = 1;
},
},
图片轮播图实现
使用
Swiper
,与首页轮播图原理类似,多了几个控制属性,不要了几个控制属性点击图片有高亮边框用
JS
实现,不用样式实现
&:hover {
border: 2px solid #f60;
padding: 1px;
}
data() {
return {
currentIndex: 0,
};
},
<img
:src="slide.imgUrl"
:class="{ active: currentIndex == index }"
@click="changeCurrentIndex(index)"
/>
methods: {
changeCurrentIndex(index) {
//修改响应式数据
this.currentIndex = index;
},
},
ImageList
与Zoom
之间要通信----点击小图上面的大图也应该跟着换—兄弟通信----全局事件总线
//ImageList通知兄弟
methods: {
changeCurrentIndex(index) {
//修改响应式数据
this.currentIndex = index;
//通知兄弟组件,当前的索引值为几
this.$bus.$emit("getIndex", this.currentIndex);
},
},
//Zoom接收
data中: currentIndex: 0,
计算属性: return this.skuImageList[this.currentIndex] || {};
mounted() {
//全局事件总线,获取兄弟组件传递过来的数据
this.$bus.$on("getIndex", (index) => {
//兄弟给了索引值,修改响应式数据
this.currentIndex = index;
});
},
放大镜实现
<div class="spec-preview">
<img :src="imgObj.imgUrl" />
<div class="event" @mousemove="handler"></div>
<div class="big">
<img :src="imgObj.imgUrl" ref="big" />
</div>
<div class="mask" ref="mask"></div>
</div>
methods: {
handler(event) {
//获取遮罩
let mask = this.$refs.mask;
let big = this.$refs.big;
let left = event.offsetX - mask.offsetWidth / 2;
let top = event.offsetY - mask.offsetHeight / 2;
//约束范围
if (left <= 0) left = 0;
if (left >= mask.offsetWidth) left = mask.offsetWidth;
if (top <= 0) top = 0;
if (top >= mask.offsetHeight) top = mask.offsetHeight;
//修改元素left top
mask.style.left = left + "px";
mask.style.top = top + "px";
big.style.left = -2 * left + "px";
big.style.top = -2 * top + "px";
},
},
购买数量操作—加减和用户输入
data(){
return{
//购买产品的个数
skuNum:1
}
},
//v-model
<input autocomplete="off" class="itxt" v-model="skuNum"/>
//加操作---不需要回调 简单操作
<a href="javascript:" class="plus" @click="skuNum++">+</a>
//减操作---注意至少为1
<a href="javascript:" class="plus" @click="skuNum > 1 ? skuNum-- : (skuNum = 1)">+</a>
//用户输入改变个数
//给表单绑定事件
@change="changeSkuNum"
//表单元素修改产品的个数
changeSkuNum(event) {
//用户输入进来的内容*1 非数字会是NaN
let value = event.target.value * 1;
//用户输入的非法,出现NaN或小于1
if (isNaN(value) || value < 1) {
this.skuNum = 1;
} else {
//大于1 但不能是小数
this.skuNum = parseInt(value);
}
},
添加购物车按钮—点击进行路由跳转
//api
//将产品添加到购物车中 (也可以更新某一个产品的个数)
// /api/cart/addToCart/{ skuId }/{ skuNum } POST
export const reqAddOrUpdateShopCart = (skuId, skuNum) => requests({ url: `/cart/addToCart/${skuId}/${skuNum}`, method: 'post' })
//store里面的detail
import { reqGoodsInfo,reqAddOrUpdateShopCart } from '@/api'
//action
//将产品添加至购物车
async addOrUpdateShopCart({commit},{skuId,skuNum}){
let result = await reqAddOrUpdateShopCart(skuId,skuNum)
}
//回到组件中 点击事件---@click="addShopCar"
<!-- 以前是简单的跳转,这里在加入购物车,进行路由跳转,发请求,把购买产品的信息通过请求的形式通知服务器,服务器进行存储 -->
<a @click="addShopCar">加入购物车</a>
//加入购物车的回调函数
addShopCar() {
//发请求
this.$store.dispatch("addOrUpdateShopCart", {
skuId: this.$route.params.skuid,
skuNum: this.skuNum,
});
//服务器存储成功---进行路由跳转传递参数
//失败---提示用户
},
//加入购物车(发请求)之后,前台将参数带给服务器
//服务器写入成功或失败只返回状态code 无其他数据,所以不需要三连环存储数据