1.主页面中导入浮动导航栏(使用vant的粘性布局sticky组件,使首屏下方的导航栏随页面滚动浮动在想要的位置):
<template> <div class="app-container"> <!-- 浮动导航 --> <van-sticky style=" z-index: 1; position: absolute; top: 12.34rem; left: 0; width: 100%; height: 0.76rem; " offset-top="0.95rem" > <tabs-index /> </van-sticky> <top-index @login="toLogin" @bind="toBindRole" /> // 这里省略页面的主要内容(即浮动栏可切换的模块内容) <foot-index /> <login-index ref="login" /> <bind-index ref="bind" /> </div> </template> <script> import store from "@/store"; import { mapGetters, mapActions } from "vuex"; import TabsIndex from "@/components/TheTabs/TabsIndex"; import TopIndex from "@/components/TheTop/TopIndex"; import LoginIndex from "@/components/TheLogin/LoginIndex"; import BindIndex from "@/components/TheBindRule/BindIndex"; import FootIndex from "@/components/TheFoot/FootIndex"; export default { name: "App", components: { TopIndex, LoginIndex, TabsIndex, BindIndex, FootIndex, }, computed: { ...mapGetters(["token", "roleId"]), }, mounted() { }, methods: { ...mapActions([ "setUser", "setPhone", ]), }, }; </script>
2.导航栏代码:
<!-- tabs --> <template> <aside> <div :class="$style.wrap" :style="{ ...otherStyle }"> <ul :class="$style.tabs"> <li v-for="(el, index) in tabList" :key="index" :class="[ $style.li, activeKey === el.value ? $style.active : '', index === 1 && creativeInfo.status && creativeInfo.status === 1 ? $style.entries : '', ]" @click="checkTab(el.value, index)" > <div :class="[$style.itemText]" :style="{ backgroundPosition: index === 3 && creativeInfo.vote_status === 2 ? `${-(0.93 * 4)}rem 0` : `${-(0.93 * index)}rem 0`, }" ></div> </li> </ul> </div> </aside> </template> <script> import { mapGetters, mapActions } from "vuex"; export default { name: "TabsIndex", components: {}, props: { otherStyle: { type: Object, default() { return {}; }, }, }, data() { return { tabList: [{ value: "1" }, { value: "2" }, { value: "3" }, { value: "4" }], activeKey: "1" }; }, computed: { ...mapGetters(["roleGifts", "creativeInfo"]), }, mounted() { window.addEventListener("scroll", this.onScroll); }, destroyed() { window.removeEventListener("scroll", this.onScroll); }, methods: { ...mapActions(["setLikeData"]), pxToRem(num) { const { clientWidth } = document.body; if (clientWidth >= 750) { return num; } return num * (clientWidth / 750); }, // 点击tab checkTab(bind_id) { this.activeKey = bind_id; const TARGET = { "1": "first", "2": "second", "3": "third", "4": "four", }; if (bind_id) { const targetObj = document.querySelector(`#j-${TARGET[bind_id]}`); if (targetObj) { const { offsetTop } = targetObj; const scrollTop = offsetTop - this.pxToRem(0); document.body.scrollTop = scrollTop; document.documentElement.scrollTop = scrollTop; } } }, onScroll(){ // 获取所有锚点元素 const targetObj = document.querySelectorAll(`.tabContent`); // 获取所有锚点元素的offsetTop const offsetTopArr = []; targetObj.forEach(item => { offsetTopArr.push(item.offsetTop); }); // 获取当前文档流的 scrollTop const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 定义当前点亮的导航下标 let navIndex = 0; for (let n = 0; n < offsetTopArr.length; n++) { // 如果scrollTop大于等于第n个元素的ofssetTop,则说明第n-1个元素的内容完全不可见,此时导航索引就是n if (scrollTop >= offsetTopArr[n]) { navIndex = n; } } this.activeKey = String(navIndex + 1); } }, }; </script> <style lang="less" module> .wrap { width: 100%; height: 0.76rem; display: flex; justify-content: center; > div:first-child { height: 100%; } } .li { position: relative; width: 23%; height: 0.5rem; text-align: center; line-height: 1; display: flex; justify-content: center; align-items: center; margin: 0 1%; } .itemText { .size(0.92rem, 0.24rem); .background-fill("./images/tab_title.png", 500% 100%); } .active { background-color: #d9c9c5; } .entries { position: relative; &::after { content: ""; position: absolute; top: 0; right: 0; width: 0.25rem; height: 0.25rem; .background-fill("./images/tab_new.png"); } } .tabs { width: 6.52rem; height: 0.76rem; .background-fill("./images/tab_bg.png"); display: flex; justify-content: space-between; padding: 0.12rem 0.32rem; box-sizing: border-box; > li { &::before { content: "|"; position: absolute; left: 102%; bottom: 0; top: 0.14rem; color: #6a4a19; font-size: 0.2rem; pointer-events: none; } } > li:last-child { &::before { display: none; } } } </style>
那么这个功能就这么做完了。