关于详情页的具体制作(五)
作者:互联网
目前下滑,已经可以看到详情图、尺码表、生产地址尺寸等、推荐等。之前做的详情页的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则可以实现啦~
标签:el,big,制作,refs,详情页,具体,offsetTop,push,themeTopY 来源: https://www.cnblogs.com/ljylearnsmore/p/14302807.html