• vue实战-产品详情页(轮播图、放大镜)


    vue实战-产品详情页(轮播图、放大镜)

    1.添加产品详情页的静态组件

    因为它是路由组件,将其放入pages文件夹下。
    注册路由组件
    1)router中添加Detail的路由。

     {
            path:'/detail/:skuid',
            component:Detail,
            meta:{show:true}
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2)在Search页面处的产品点击跳转处,设置声明式导航跳转

     <router-link :to="`/detail/${good.id}`">
      <img :src="good.defaultImg" />
     router-link>
    
    • 1
    • 2
    • 3

    2.设置详情页的api接口

    在文件夹api下的接口统一管理中添加获得接口数据的函数reqDetailInfo,
    需要传入产品的ID

    // /api/item/{ skuId }
    export const reqDetailInfo = (skuId) =>{
        return requests({url:`/item/${skuId}`,method:'get'})
    }
    
    • 1
    • 2
    • 3
    • 4

    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在Detail组件下派发actions,触发数据进库。

    mounted() {
        this.$store.dispatch("getDetailList", this.$route.params.skuid);
      },
    
    • 1
    • 2
    • 3

    通过getters处理,组件获得仓库中的数据

    import { mapGetters } from "vuex";
    
     computed: {
        ...mapGetters([ "categoryView", "skuInfo", "spuSaleAttrList" ]),
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    放大镜与轮播图

    父组件

    
     <Zoom :skuImageList="skuInfos" />
     
    <ImageList :skuImageList="skuInfos" />
    
    • 1
    • 2
    • 3
    • 4

    轮播图
    轮播图子组件

    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    传值以及逻辑控制、动态轮播图

    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)
          }
        },
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    放大镜
    子组件

    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    放大镜逻辑设置、参数动态传递逻辑

    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.ms
            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
    
            //修改mask的属性值
            mask.style.left = left+'px'
            mask.style.top = top+'px'
            big.style.left = -2*left +'px'
            big.style.top = -2*top + 'px'
          }
        },
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    结果展示

    在这里插入图片描述

  • 相关阅读:
    Spring MVC 和 @ModelAttribute 注释
    基于Python实现的五子棋游戏设计(alpha-beta剪枝技术)
    软件测试、交付与维护
    【预测模型-ELM分类】基于极限学习机ELM+OSELM+KELM+半监督SSELM+USELM实现数据集分类附matlab代码
    【PCB学习】几种接地符号
    阿里三面:CAP和BASE理论了解么?可以结合实际案例说下?
    Maven | 依赖
    五年数据库专家,带你深入高性能 MySQL 架构系统,不要等到面试再追悔莫及
    OceanBase 4.0 - 从分布式到单机,从单机到分布式
    HNUCM-2022年秋季学期《算法分析与设计》练习12
  • 原文地址:https://blog.csdn.net/bying666/article/details/127144410