vue tab滾動(dòng)到一定高度,固定在頂部,點(diǎn)擊tab切換不同的內(nèi)容操作
template里面:
<!-- tab切換star --> <ul class="tab-list" :class="{fixTitle:whether}"> <li @click="curId=0" :class="{'cur':curId===0}">產(chǎn)品特點(diǎn)</li> <li @click="curId=1" :class="{'cur':curId===1}">投保須知</li> <li @click="curId=2" :class="{'cur':curId===2}">理賠流程</li> </ul> <!-- 切換內(nèi)容star -->
設(shè)置fixTitle的樣式,固定在頂部,cur是當(dāng)前tab點(diǎn)擊的顏色
<div class="tab-con"> <div v-show="curId===0"> 第一部分內(nèi)容 </div> <div v-show="curId===1"> 第二部分內(nèi)容 </div> <div v-show="curId===2"> 第三部分內(nèi)容 </div> </div>
當(dāng)點(diǎn)擊第一個(gè)產(chǎn)品特點(diǎn)的時(shí)候,對(duì)應(yīng)下面的第一部分內(nèi)容,點(diǎn)擊投保須知對(duì)應(yīng)第二部分內(nèi)容,點(diǎn)擊理賠流程對(duì)應(yīng)第三部分內(nèi)容
data里面:
data(){ return:{ whether:false, curId:0 } }
curId默認(rèn)為0,展示的是產(chǎn)品特點(diǎn)的內(nèi)容,也就是第一部分內(nèi)容
methods里面:
設(shè)置滾動(dòng)效果:
handleScroll() { var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; // console.log(scrollTop) if(scrollTop>329){ this.whether = true; }else{ this.whether = false; } },
在mounted里面:
window.addEventListener("scroll", this.handleScroll);
補(bǔ)充知識(shí):vue組件之自定義tab切換組件(吸頂、滾動(dòng)定位)等效果
目標(biāo)問題
進(jìn)入頁面后,滾動(dòng)一定距離使其吸頂。滾動(dòng)到某DOM可視區(qū)域后,Tab攔當(dāng)前選項(xiàng)主動(dòng)滑動(dòng)到該DOM上。且點(diǎn)擊tab攔會(huì)定位到對(duì)應(yīng)的dom位置。
實(shí)現(xiàn)效果動(dòng)圖
實(shí)現(xiàn)目的——html結(jié)構(gòu)
<template> <div class="tab__main" :style="prop.box_style ? prop.box_style : ''"> <div class="tab__div"> <ul class="tab__list" :style="prop.attr.tab_style ? prop.attr.tab_style : ''"> <li class="tab__item" v-for="(tabs, index) in prop.attr.tab_content" :key="tabs.tab_menu" @click="onClickTabs(index)" > <span :style="tabStyle(index)">{{ tabs.tab_menu }}</span> </li> </ul> <div class="active__line" :style="prop.attr.cur_slide_style ? prop.attr.cur_slide_style : ''"></div> </div> </div> </template>
實(shí)現(xiàn)目的——less樣式
.tab__div { width: 100%; height: 102px; position: relative; padding-top: 36px; background-color: #fff; .tab__list { display: flex; .tab__item { flex: 1; font-size: 32px; } .tab__item-current { font-weight: 700; } } .active__line { position: absolute; bottom: 0; left: 0; width: 187.5px; height: 5px; background-color: #4B8FFB; transition: all 300ms; } }
實(shí)現(xiàn)目的——js部分
export default { name: 'TabModule', props: { prop: { type: Object } }, data () { return { scrolltop: null, dom: null, domobj: {} // 各個(gè)dom的頁面位置 } }, computed: { tabStyle () { return function (params) { return this.prop.attr.tab_content[params].tab_style || '' } } }, mounted () { this.onWatchScroll() // 這里首次進(jìn)入頁面當(dāng)前選中項(xiàng)為第一個(gè) document.querySelectorAll('.tab__item')[0].style = this.prop.attr.cur_tab_style ? this.prop.attr.cur_tab_style : '' }, methods: { // 獲取各個(gè)dom的頁面位置 getDomsObj () { this.domobj.dom1 = document.querySelectorAll(`#${this.prop.attr.tab_content[0].anchor_point}`)[0].offsetTop this.domobj.dom2 = document.querySelectorAll(`#${this.prop.attr.tab_content[1].anchor_point}`)[0].offsetTop this.domobj.dom3 = document.querySelectorAll(`#${this.prop.attr.tab_content[2].anchor_point}`)[0].offsetTop this.domobj.dom4 = document.querySelectorAll(`#${this.prop.attr.tab_content[3].anchor_point}`)[0].offsetTop }, // 計(jì)算當(dāng)前選中滑動(dòng)塊兒的滑動(dòng)距離和當(dāng)前選中項(xiàng) computerSlide (val) { let tablist = document.querySelectorAll('.tab__item') for (let i = 0; i < tablist.length; i++) { tablist[i].style = '' } document.querySelector('.active__line').style.transform = `translateX(${(val * document.querySelector('.active__line').offsetWidth)}px)` // 當(dāng)前選中的tab_item的狀態(tài) tablist[val].style = this.prop.attr.cur_tab_style ? this.prop.attr.cur_tab_style : '' }, onClickTabs (index) { this.computerSlide(index) // 計(jì)算點(diǎn)擊后滑動(dòng)到DOM的位置 this.dom = document.querySelectorAll(`#${this.prop.attr.tab_content[index].anchor_point}`)[0].offsetTop let tabbox = document.querySelectorAll('.tab__div')[0] if (index === 0) { if (tabbox.style.position === 'relative') { window.scrollTo(0, this.dom - tabbox.clientHeight) return } window.scrollTo(0, this.dom) return } if (index === 3) { window.scrollTo(0, this.dom) return } if (tabbox.style.position === 'relative') { window.scrollTo(0, this.dom - (tabbox.clientHeight * 2)) } else { window.scrollTo(0, this.dom - tabbox.clientHeight) } }, onWatchScroll () { let tabmain = document.querySelectorAll('.tab__main')[0] let tabdiv = document.querySelectorAll('.tab__div')[0] tabdiv.style.top = 0 window.onscroll = () => { // 由于在created()或者mounted()鉤子函數(shù)中獲取到的dom位置不對(duì),在滑動(dòng)中獲取dom的頁面位置 this.getDomsObj() this.scrolltop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset // 滑動(dòng)根據(jù)滾動(dòng)距離來計(jì)算當(dāng)前可是區(qū)域的選中項(xiàng) this.onScrollPage() // 自定義吸頂效果 if (this.scrolltop > tabmain.offsetTop) { tabdiv.style.position = 'fixed' tabdiv.style['z-index'] = 99 } else { tabdiv.style.position = 'relative' tabdiv.style['z-index'] = 0 } } }, onScrollPage () { let tab = document.querySelectorAll('.tab__div')[0] if (this.scrolltop > this.domobj.dom1 && this.scrolltop < (this.domobj.dom2 - tab.offsetHeight * 2)) { this.computerSlide(0) } else if (this.scrolltop > (this.domobj.dom2 - tab.offsetHeight * 2) && this.scrolltop < this.domobj.dom3 - tab.offsetHeight * 2) { this.computerSlide(1) } else if (this.scrolltop > (this.domobj.dom3 - tab.offsetHeight * 2) && this.scrolltop < (this.domobj.dom3 + tab.offsetHeight * 2)) { this.computerSlide(2) } else if (this.scrolltop > (this.domobj.dom4 - tab.offsetHeight * 10) && this.scrolltop < this.domobj.dom4) { this.computerSlide(3) } } } }
完成目的——頁面引用組件
<template> <div> <div class="div__header"></div> <tab-module :prop="tabattributes"></tab-module> <div :id="tabattributes.attr.tab_content[index].anchor_point" class="div__item" v-for="(item, index) in fordiv" :key="item">{{ item }}</div> <div class="div__footer">我是有底線的</div> </div> </template> import TabModule from '../../components/TabModule.vue' export default { components: { TabModule }, data () { return { tabattributes: { box_style: "margin-top: 10px;", attr: { cur_tab_style: "font-weight: 700;", cur_slide_style: "", tab_content: [{ tab_menu: "控件1", anchor_point: "DomPoint1", tab_style: "" }, { tab_menu: "控件2", anchor_point: "DomPoint2", tab_style: "" }, { tab_menu: "控件3", anchor_point: "DomPoint3", tab_style: "" }, { tab_menu: "控件4", anchor_point: "DomPoint4", tab_style: "" }] } }, fordiv: ['頁面控件1', '頁面控件2', '頁面控件3', '頁面控件4'] } } } <style lang="less" scoped> .div__header { width: 100%; height: 200px; background-color: #909; } .div__item { width: 100%; height: 400px; background-color: rgb(78, 215, 224); text-align: center; font-size: 26px; } .div__footer { width: 100%; height: 200px; background-color: #090; } </style>
以上這篇vue tab滾動(dòng)到一定高度,固定在頂部,點(diǎn)擊tab切換不同的內(nèi)容操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法
在父組件 App.vue 中引用子組件 A.vue,把 name 的值傳給 A 組件。這篇文章主要介紹了vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法,需要的朋友可以參考下2018-01-01vue的diff算法知識(shí)點(diǎn)總結(jié)
本篇文章給大家分享了關(guān)于vue的diff算法的相關(guān)知識(shí)點(diǎn)總結(jié),有興趣的朋友參考學(xué)習(xí)下。2018-03-03vue路由組件路徑如何用變量形式動(dòng)態(tài)引入
這篇文章主要介紹了vue路由組件路徑如何用變量形式動(dòng)態(tài)引入問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Vue中對(duì)拿到的數(shù)據(jù)進(jìn)行A-Z排序的實(shí)例
今天小編就為大家分享一篇Vue中對(duì)拿到的數(shù)據(jù)進(jìn)行A-Z排序的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09在vue項(xiàng)目中使用Nprogress.js進(jìn)度條的方法
NProgress.js是輕量級(jí)的進(jìn)度條組件,使用簡便,可以很方便集成到單頁面應(yīng)用中。這篇文章主要介紹了在vue項(xiàng)目中使用Nprogress.js進(jìn)度條的方法,需要的朋友可以參考下2018-01-01