1. 程式人生 > 實用技巧 >關於詳情頁的具體制作(五)

關於詳情頁的具體制作(五)

目前下滑,已經可以看到詳情圖、尺碼錶、生產地址尺寸等、推薦等。之前做的詳情頁的navbar就存在著”商品“、“引數”、“討論”與“推薦”四個模組。那麼,現在想要實現的功能,即為點選navbar中的某一塊,即可跳轉到相應的位置。

那麼,接下來即開始一個正式的實現。首先,我們之前做詳情裡面的navbar的時候,就已經將其封裝在了一個元件裡面。那我們需要把這個點選事件傳到詳情頁主頁,nav元件的程式碼如下:

<template>
  <div class="bbb">
    <navbar>
      <div slot="left" class="left" @click="backclick">
        <img src="../../../src/assets/img/back.svg">
      </div>
      <div slot="center" class="title">
        <div v-for
="(item,index) in title" class="aaa" :class="{active:index === currentIndex}" v-on:click="itemclick(index)"> {{item}} </div> </div> </navbar> </div> </template> <script> import Navbar from "../../../src/components/common/navbar/navbar"; export
default { name: "detailnav", components: {Navbar}, data(){ return{ title:['商品','引數','討論','推薦'], currentIndex:0 } }, methods:{ itemclick(index){ this.currentIndex = index this.$emit("itemclick",index) }, backclick(){ this.$router.back() } } }
</script> <style scoped> .title{ display: flex; font-size: 13px; } .aaa{ flex: 1; } .active{ color: greenyellow; } .left img{ margin-top: 10px; } .bbb{ background-color: #f6f6f6; /*height: 100vh;*/ } </style>

之後,我們在detail.vue中對其進行一個監聽:

<detailnav class="nav" @itemclick="itemclick"></detailnav>
itemclick(index) {
      console.log(index);
      this.$refs.scroll.scrollTo(0, -this.themeTopY[index], 1000)
    }
 data() {
    return {
      themeTopY:[ ]
    }
  }

初始化themeTopY陣列,計算出每一個模組的相應offsetTop,將其傳入空陣列中,然後在上述的itemclick事件中,執行scrollTo函式到相應的選項中即可。

新增每個模組的offsetTop還是很清晰的,有兩種方法,最開始想的push,後面反應過來直接賦值好像更簡單哈哈哈,都可。

 this.themeTopY =[ ]
        this.themeTopY.push(0)
        this.themeTopY.push(this.$refs.params.$el.offsetTop)
        this.themeTopY.push(this.$refs.comment.$el.offsetTop)
        this.themeTopY.push(this.$refs.recommend.$el.offsetTop)

或者,直接設定themeTopY= [0,0,0,0],之後在其中給每個賦值即可。

this.themeTopY[0] = 0
this.themeTopY[1] = this.$refs.params.$el.offsetTop
this.themeTopY[2] = this.$refs.comment.$el.offsetTop
this.themeTopY[3] = this.$refs.recommend.$el.offsetTop

之後我測試了幾次在各個位置,created當中是肯定不行的,直接否認,壓根獲取不了元素。

mounted當中也不行,資料還沒有獲得到;獲取到資料的回撥中也不行,DOM還沒有渲染完畢;$nextTick也不行,因為圖片的高度沒有被計算在裡面。

因此,最後我把它放入了refresh()之後,終於實現哈哈哈。

<template>
<div id="detail">
<detailnav class="nav" @itemclick="itemclick"></detailnav>
  <scroll class="content" ref="scroll">
  <detailswiper :top-images="topImages"></detailswiper>
  <detailbaseinfo :good="good"></detailbaseinfo>
  <detailshopinfo :shop="shop"></detailshopinfo>
    <detailgoods :detail-info="detailInfo" @imageload="imageLoad"></detailgoods>
    <detailparaminfo :param-info="paramInfo" ref="params"></detailparaminfo>
    <detailcommentinfo :comment-info="commentInfo" ref="comment"></detailcommentinfo>
    <goodslist :goods="recommends" ref="recommend"></goodslist>
  </scroll>
</div>
</template>

<script>
import Detailnav from "./childcomponent/detailnav";
import {getdetails, Good, GoodsParam, shop,getrecommend} from "../../network/detail";
import detailswiper from "./childcomponent/detailswiper";
import detailbaseinfo from "./childcomponent/detailbaseinfo";
import detailshopinfo from "./childcomponent/detailshopinfo";
import scroll from "../../src/components/common/scroll/scroll";
import detailgoods from "./childcomponent/detailgoods";
import detailparaminfo from "./childcomponent/detailparaminfo";
import detailcommentinfo from "./childcomponent/detailcommentinfo";
import goodslist from "../../src/components/content/goods/goodslist";
import {debounce} from "../../src/components/common/utils/utils";
export default {
  name: "detail",
  components: {Detailnav, detailswiper,detailbaseinfo,detailshopinfo,scroll,detailgoods,detailparaminfo,detailcommentinfo,goodslist},
  data() {
    return {
      iid: null,
      topImages: [],
      good:{ },
      shop:{ },
      detailInfo:{},
      paramInfo:{ },
      commentInfo:{ },
      recommends:[ ],
      refresh: undefined,
      themeTopY:[0, 0, 0, 0]
    }
  },
  created() {
    this.getdetails()
    this.getrecommend()
// // 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.topImages = big.itemInfo.topImages
//       console.log(this.topImages)
//       this.good = new Good(big.itemInfo, big.columns, big.shopInfo)
//       this.shop = new shop(big.shopInfo)
//       this.detailInfo = big.detailInfo
//       this.paramInfo = new GoodsParam(big.itemParams.info, big.itemParams.rule );
//       if (big.rate.list){
//         this.commentInfo = big.rate.list[0]
//       }
//     })
//     getrecommend().then(res =>{
//         console.log(res)
//         this.recommends = res.data.data.list
//       }
//
//     )
    // this.$nextTick(()=>{
    //     this.themeTopY =[ ]
    //     this.themeTopY.push(0)
    //     this.themeTopY.push(this.$refs.params.$el.offsetTop)
    //     this.themeTopY.push(this.$refs.comment.$el.offsetTop)
    //     this.themeTopY.push(this.$refs.recommend.$el.offsetTop)
    //     console.log(this.themeTopY)
    // })
    // activated() {
    //   this.iid = this.$route.params.iid
    //   console.log(this.$route.params.iid)
    //
    //   })
    // }
  },
  mounted(){
    this.refresh = debounce(this.$refs.scroll.refresh, 1000)
  },
  updated() {
    // this.themeTopY =[ ]
    // this.themeTopY.push(0)
    // this.themeTopY.push(this.$refs.params.$el.offsetTop)
    // this.themeTopY.push(this.$refs.comment.$el.offsetTop)
    // this.themeTopY.push(this.$refs.recommend.$el.offsetTop)
    // // this.themeTopY.push(Number.MAX_VALUE)
    // console.log(this.themeTopY)
  },
  methods: {
    imageLoad() {
      this.refresh()
      // console.log("refresh no debounce")
      //   this.themeTopY =[ ]
      //   this.themeTopY.push(0)
      //   this.themeTopY.push(this.$refs.params.$el.offsetTop)
      //   this.themeTopY.push(this.$refs.comment.$el.offsetTop)
      //   this.themeTopY.push(this.$refs.recommend.$el.offsetTop)
      this.themeTopY[0] = 0
      this.themeTopY[1] = this.$refs.params.$el.offsetTop
      this.themeTopY[2] = this.$refs.comment.$el.offsetTop
      this.themeTopY[3] = this.$refs.recommend.$el.offsetTop
        console.log(this.themeTopY)
    },
    itemclick(index) {
      console.log(index);
      this.$refs.scroll.scrollTo(0, -this.themeTopY[index], 1000)
    },
   getdetails(){
     this.iid = this.$route.params.iid
      getdetails(this.iid).then(res => {
        console.log(res)
        const big = res.data.result
        this.topImages = big.itemInfo.topImages
        console.log(this.topImages)
        this.good = new Good(big.itemInfo, big.columns, big.shopInfo)
        this.shop = new shop(big.shopInfo)
        this.detailInfo = big.detailInfo
        this.paramInfo = new GoodsParam(big.itemParams.info, big.itemParams.rule );
        if (big.rate.list) {
          this.commentInfo = big.rate.list[0]
        }
        // this.$nextTick(()=>{
        //   this.themeTopY =[ ]
        //   this.themeTopY.push(0)
        //   this.themeTopY.push(this.$refs.params.$el.offsetTop)
        //   this.themeTopY.push(this.$refs.comment.$el.offsetTop)
        //   this.themeTopY.push(this.$refs.recommend.$el.offsetTop)
        //   // this.themeTopY.push(Number.MAX_VALUE)
        //   console.log(this.themeTopY)
        // })
      })
        },
    getrecommend(){
      getrecommend().then(res =>{
        console.log(res)
        this.recommends = res.data.data.list
      })
    }

      }

}
</script>

<style scoped>
#detail{
  position: relative;
  z-index:9;
  background-color: #f6f6f6;
  height: 100vh;
}
.content{
  /*height: calc(100vh  - 44px);*/
  position: absolute;
  top: 44px;
  bottom: 60px;
}
.nav{
  position: relative;
  z-index: 9;
}
</style>

這裡就基本實現了,但是還是有個問題,每次點選navbar中相應的模組的時候,都會擋住一些navbar中後三個模組的高度。(因為我最開始把滾動模組設定了relative,且把height設定為calc(100vh - 44px) ,因此後期我把其設定為絕對定位,固定其top:44px,bottom:60px則可以實現啦~