vue实战-产品详情页(轮播图、放大镜)
1.添加产品详情页的静态组件
因为它是路由组件,将其放入pages文件夹下。
注册路由组件
1)router中添加Detail的路由。
{path:'/detail/:skuid',component:Detail,meta:{show:true}},
2)在Search页面处的产品点击跳转处,设置声明式导航跳转
<router-link :to="`/detail/${good.id}`"><img :src="good.defaultImg" /></router-link>
2.设置详情页的api接口
在文件夹api下的接口统一管理中添加获得接口数据的函数reqDetailInfo,
需要传入产品的ID
// /api/item/{ skuId }export const reqDetailInfo = (skuId) =>{return requests({url:`/item/${skuId}`,method:'get'})}
3.创建关于产品详情的仓库(vuex)
在文件夹store下
import {reqDetailInfo } from "@/api"const state = {detailList:{}}const mutations = {GETDETAILLIST(state,detailList){state.detailList = detailList}}const actions = {async getDetailList({commit},skuid){let result = await reqDetailInfo(skuid)if(result.code==200){commit('GETDETAILLIST',result.data)}}}const getters = {categoryView(state){return state.detailList.categoryView},skuInfo(state){return state.detailList.skuInfo},spuSaleAttrList(state){return state.detailList.spuSaleAttrList}}export default {state,mutations,actions,getters}
在Detail组件下派发actions,触发数据进库。
mounted() {this.$store.dispatch("getDetailList", this.$route.params.skuid);},
通过getters处理,组件获得仓库中的数据
import {mapGetters } from "vuex";computed: {...mapGetters([ "categoryView", "skuInfo", "spuSaleAttrList" ]),}
4.动态数据展示
左侧导航处
<!-- 导航路径区域 --><div class="conPoin"><span v-show="categoryName.category1Name">{{categoryName.category1Name}}</span><span v-show="categoryName.category2Name">{{categoryName.category2Name}}</span><span v-show="categoryName.category3Name">{{categoryName.category3Name}}</span></div>
放大镜与轮播图
父组件
<!--放大镜效果--><Zoom :skuImageList="skuInfos" /><!-- 小图列表 --><ImageList :skuImageList="skuInfos" />
轮播图
轮播图子组件
<div class="swiper-container" ref="cur"><div class="swiper-wrapper"><div class="swiper-slide" v-for="(skuImage,index) in skuImageList.skuImageList" :key="skuImage.id"><img :src="skuImage.imgUrl" :class="{active:currentIndex==index}" @click="changeCurrentIndex(index)"></div></div><div class="swiper-button-next"></div><div class="swiper-button-prev"></div></div>
传值以及逻辑控制、动态轮播图
import Swiper from 'swiper'export default {name: "ImageList",data() {return {currentIndex:0}},props:[ 'skuImageList' ],//轮播图监听watch:{skuImageList:{immediate:true,handler(){this.$nextTick(()=>{new Swiper (this.$refs.cur, {// 如果需要前进后退按钮navigation: {nextEl: '.swiper-button-next',prevEl: '.swiper-button-prev',},slidesPerView:3,slidesPerGroup:1}) })}}},methods: {changeCurrentIndex(index){this.currentIndex = index//全局事件总线传值给兄弟组件zoom组件,判断此时点击的是哪张图片this.$bus.$emit('getIndex',this.currentIndex)}},}
放大镜
子组件
<template><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="ms"></div></div></template>
放大镜逻辑设置、参数动态传递逻辑
export default {name: "Zoom",data() {return {currentIndex:0}},props:[ 'skuImageList' ],computed:{//防止传来的值还没有值,用一个空数组来代替imgObj(){return this.skuImageList.skuImageList[this.currentIndex] || []}},//全局事件总线的绑定mounted(){this.$bus.$on('getIndex',(index)=>{this.currentIndex = index})},methods: {//放大镜核心函数handler(event){let mask = this.$refs.mslet big = this.$refs.biglet left = event.offsetX - mask.offsetWidth/2let top = event.offsetY - mask.offsetHeight/2if(left < 0) left = 0if(left >= mask.offsetWidth) left = mask.offsetWidthif(top < 0) top = 0if(top >= mask.offsetHeight) top = mask.offsetHeight//修改mask的属性值mask.style.left = left+'px'mask.style.top = top+'px'big.style.left = -2*left +'px'big.style.top = -2*top + 'px'}},}