关于详情页的具体制作(三)

详情页店铺后面的图片详情展示、穿着效果这些的展示的部分思路与代码的记录。

首先,我们需要实现的是将接口中我们所需展示到此的数据保存在data中,那么即可在detail.vue中先进行如下操作。

  data() {
    return {
      detailInfo:{}
    }
  },
  created() {
    // console.log(this.$route.params.iid)
    this.iid = this.$route.params.iid
    getdetails(this.iid).then(res => {
      console.log(res);
      const big = res.data.result;
      this.detailInfo = big.detailInfo
      }
    })

  }

之后我们封装一个相应组件并将需要的数据传入该组件中,并在detail.vue中注册该组件。

detailgoods里面:

 props: {
    detailInfo: {
      type: Object
    }
  }

之后在detail.vue中去注册且引入该组件,并绑定相应数据:

<detailgoods :detail-info="detailInfo""></detailgoods>
import detailgoods from "./childcomponent/detailgoods";
components: {Detailnav, detailswiper,detailbaseinfo,detailshopinfo,scroll,detailgoods}

后期,我们即可在detailgoods组件中按照相应的需求效果实现啦~

<template>
  <div v-if="Object.keys(detailInfo).length !== 0" class="goods-info">
    <div class="info-desc clear-fix">
      <div class="start">
      </div>
      <div class="desc">{{detailInfo.desc}}</div>
      <div class="end"></div>
    </div>
    <div class="info-key">{{detailInfo.detailImage[0].key}}</div>
    <div class="info-list">
      <img v-for="(item, index) in detailInfo.detailImage[0].list" :src="item" alt="" @load="imgLoad" :key="index">
    </div>
  </div>
</template>

<script>

export default {
  name: "DetailGoodsInfo",
  props: {
    detailInfo: {
      type: Object
    }
  },
  data(){
    return{
      counter:0,
      imagesLength:0
    }
  },
methods:{
    imgLoad(){
      this.$emit("imageload")
    }
}
  // methods:{
  //   imgLoad(){
  //     if (++this.counter === this.imagesLength) {
  //
  //       this.$emit('imageload')
  //     }
  //   }
  //   },
  // watch:{
  //   detailInfo(){
  //     this.imagesLength = this.detailInfo.detailImage[0].list.length
  //   }
  // }
  }

</script>

<style scoped>
.goods-info {
  padding: 20px 0;
  border-bottom: 5px solid #f2f5f8;
}

.info-desc {
  padding: 0 15px;
}

.info-desc .start, .info-desc .end {
   90px;
  height: 1px;
  background-color: #a3a3a5;
  position: relative;
}

.info-desc .start {
  float: left;
}

.info-desc .end {
  float: right;
}

.info-desc .start::before, .info-desc .end::after {
  content: '';
  position: absolute;
   5px;
  height: 5px;
  background-color: #333;
  bottom: 0;
}

.info-desc .end::after {
  right: 0;
}

.info-desc .desc {
  padding: 15px 0;
  font-size: 14px;
}

.info-key {
  margin: 10px 0 10px 15px;
  color: #333;
  font-size: 15px;
}

.info-list img {
   100%;
}
</style>

这里主要注意一个点:由于使用bscroll插件,由于最开始图片还未加载完全,那么原本bscroll中那个长度值是未包含所有图片都加载进去的值的。因此,有时候上拉加载会有卡顿,为了解决这个问题,之前我们也说过,需要使用refresh函数来对其进行处理,那么为了不多次调用refresh,可以用两种方法进行处理。

第一种的话,比如使用debounce函数:

首先,先在图片上进行一个监听,监听其中图片完全加载完毕。之后在methods里面,进行一个发送,将其发送给父组件detail.vue。那么下方就是对detail.vue中进行一定的处理。(debounce在首页中也用使用到,因此被我封装起来了,直接调入在此处使用)

  mounted(){
    this.refresh = debounce(this.$refs.scroll.refresh, 1000)
  },
  methods:{
    imageLoad(){
      this.refresh()
      // console.log("refresh no debounce")
    }
  }

或者,第二种方法,即为在detailgoods里面,直接在data当中初始化一个图片个数以及图片数量,当这两者相等时,才会去发射出相应的事件给父组件。因此在上述的注释代码中,有一个这两者之间的判断,并设置了一个watch函数,watch是监听属性值的变化,只要属性值发生变化就会调用watch对应的函数。之后再在父组件中直接写一个imageLoad事件,使用this.$refs.scroll.refresh即可。

原文地址:https://www.cnblogs.com/ljylearnsmore/p/14292890.html