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í)候,對應(yīng)下面的第一部分內(nèi)容,點(diǎn)擊投保須知對應(yīng)第二部分內(nèi)容,點(diǎn)擊理賠流程對應(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ǔ)充知識: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ì)定位到對應(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位置不對,在滑動(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-01
vue路由組件路徑如何用變量形式動(dòng)態(tài)引入
這篇文章主要介紹了vue路由組件路徑如何用變量形式動(dòng)態(tài)引入問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue中對拿到的數(shù)據(jù)進(jìn)行A-Z排序的實(shí)例
今天小編就為大家分享一篇Vue中對拿到的數(shù)據(jù)進(jìn)行A-Z排序的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
在vue項(xiàng)目中使用Nprogress.js進(jìn)度條的方法
NProgress.js是輕量級的進(jìn)度條組件,使用簡便,可以很方便集成到單頁面應(yīng)用中。這篇文章主要介紹了在vue項(xiàng)目中使用Nprogress.js進(jìn)度條的方法,需要的朋友可以參考下2018-01-01

