關於詳情頁的具體制作(五)
阿新 • • 發佈:2021-01-21
目前下滑,已經可以看到詳情圖、尺碼錶、生產地址尺寸等、推薦等。之前做的詳情頁的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"; exportdefault { 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則可以實現啦~