vue 页面滚动到一定高度,Tab吸顶

1、template

<template>
    <div class="find-home-page">
        <header :style="bgStyle">
            <i class="iconfont icon-fanhui" @click="$router.go(-1)"></i>
            <i class="iconfont icon-common-more"></i>
        </header>
        <div class="top-box" id="topWrap">
            <div class="user-info">
                <img :src="userInfo.icon" :onerror="defaultAvatar">
                <div class="info-box">
                    <p class="name">
                        {{ userInfo.nickName }}
                        <i 
                            class="iconfont"
                            :class="{ 
                                'icon-woman': userInfo && userInfo.gender === 2, 
                                'icon-nan': userInfo && userInfo.gender === 1,
                                'icon-biangengxingbie': userInfo && userInfo.gender ===0
                            }">
                        </i>
                    </p>
                    <p class="account">买易买账号:{{ userInfo.id }}</p>
                    <span class="change-bg" v-if="isSelf">
                        <i class="iconfont icon-iconfontzhizuobiaozhun47"></i>
                        更换背景
                    </span>
                </div>
            </div>
            <div class="total-nums">
                <div class="item" @click="goFriendList(1)">
                    <p class="num">{{ userInfo.followNum }}</p>
                    <p class="label">关注</p>
                </div>
                <div class="item" @click="goFriendList(2)">
                    <p class="num">{{ userInfo.fansNum }}</p>
                    <p class="label">粉丝</p>
                </div>
                <div class="item" @click="goFriendList(3)">
                    <p class="num">{{ userInfo.likedNum }}</p>
                    <p class="label">被喜欢</p>
                </div>
                <div class="btn">
                    <span class="share" v-if="isSelf" @click="turnPage">发布分享</span>
                    <span 
                        v-else
                        :class="{ 'care': !userInfo.isFollow }" 
                        @click="clickCare">
                        {{ userInfo.isFollow ? "已关注" : "关注" }}
                    </span>
                    <i class="iconfont icon-chat"></i>
                </div>
            </div>
        </div>
        <ul class="tab-box" :class="{ 'fixed-top': tabFixed }">
            <li
                v-for="(item, index) of tabList"
                :key="index"
                @click="changeTab(index)"
                :class="{ 'active': activetab == index }">
                {{ item.label + "(" + item.num + ")" }}
            </li>
        </ul>
        <div class="tab-container">
            <Empty v-if="!list.length" :empty_type="{name: '快来发布你的第一篇笔记吧'}"></Empty>
            <List
        ref="list"
        :url="url"
                :params="params"
        method="get"
        :on-getdata="onGetdata"
        :showText="list && list.length > 0"
      >
        <div
          slot="item"
          class="item"
          v-for="(item, index) in list"
          :key="index"
            >
                    <CareCell :showUserInfo="false" :data="item">
                        <template #bt-operate>
                            <p class="bt-userinfo">
                                <span>
                                    <img :src="userInfo.icon" :onerror="defaultAvatar">
                                    {{ userInfo.nickName }}
                                </span>
                                <span>
                                    <i class="iconfont icon-aixin"></i>
                                    {{ item.likeNum }}
                                </span>
                                <i @click.stop="delArticle(item)" v-if="isSelf" class="iconfont icon-shanchu1"></i>
                                <i @click.stop="editArticle(item)" v-if="isSelf && activetab == 1" class="iconfont icon-bianji"></i>
                            </p>
                        </template>
                    </CareCell>
                </div>
            </List>
        </div>
    </div>
</template>

2、style

<style lang="scss" scoped>
    .find-home-page {
        background: #f4f4f4;
        height: 100vh;
        header {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            background: rgba(255, 255, 255, 0);
            color: #fff;
            @extend %flex-space-between;
            padding: 0 32px;
            height: 98px;
            line-height: 98px;
            z-index: 9999;
            i {
                font-size: 40px;
                opacity: 1;
            }
        }
        .top-box {
            background: #3A5577;
            padding: 150px 32px 180px;
            color: #fff;
            .user-info {
                margin-bottom: 80px;
                img {
                    width: 166px;
                    height: 166px;
                    border-radius: 50%;
                    vertical-align: bottom;
                    margin-right: 32px;
                }
                .info-box {
                    height: 166px;
                    display: inline-flex;
                    flex-direction: column;
                    justify-content: space-evenly;
                    .name {
                        font-size: 30px;
                        font-weight: 800;
                        i {
                            font-size: 32px;
                            &.icon-biangengxingbie {
                                color: #10B182;
                            }
                            &.icon-nan {
                                color: #4EA1FD;
                            }
                            &.icon-woman {
                                color: #FF6BD5;
                            }
                        }
                    }
                    .account {
                        font-size: 20px;
                    }
                    .change-bg {
                        font-size: 20px;
                        background: rgba(255, 255, 255, .17);
                        width: 138px;
                        height: 36px;
                        line-height: 36px;
                        border-radius: 18px;
                        text-align: center;
                        i {
                            color: #FFCB21;
                            vertical-align: middle;
                            font-size: 28px;
                        }
                    }
                }
            }
            .total-nums {
                display: flex;
                align-items: center;
                .item {
                    margin-right: 80px;
                    text-align: center;
                    .num {
                        font-size: 30px;
                        margin-bottom: 20px;
                    }
                    .label {
                        font-size: 22px;
                    }
                }
                .btn {
                    flex: 1;
                    text-align: center;
                    span {
                        display: inline-block;
                        width: 160px;
                        height: 60px;
                        line-height: 60px;
                        border-radius: 30px;
                        text-align: center;
                        font-size: 26px;
                        border: 1px solid #fff;
                        &.share {
                            border: 1px solid #fff;
                        }
                        &.care {
                            background: #DE0F0F;
                            border: 1px solid #DE0F0F;
                        }
                    }
                    i {
                        font-size: 40px;
                        margin-left: 40px;
                    }
                }
            }
        }
        .tab-box {
            position: relative;
            @extend %flex-center;
            background: #fff;
            border-radius: 50px 50px 0px 0px;
            height: 90px;
            line-height: 90px;
            margin-top: -90px;
            background: #fff;
            padding-bottom: 20px;
            li {
                flex: 1;
                text-align: center;
                color: #666;
                font-size: 26px;
                font-weight: bold;
                &.active {
                    color: #333;
                    position: relative;
                    &::after {
                        content: "";
                        position: absolute;
                        width: 78px;
                        height: 6px;
                        background: #FC2621;
                        border-radius: 3px;
                        left: 50%;
                        transform: translateX(-50%);
                        bottom: 10px;
                    }
                }
            }
            &.fixed-top {
                position: fixed;
                top: 188px;
                left: 0;
                right: 0;
                z-index: 9999;
            }
            &::after {
            width: 100vw;
            height: 20px;
            background: #F4F4F4;
            content: "";
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
        }
        }
        .tab-container {
            .cell-wrap {
                .bt-userinfo {
                    padding: 20px 0;
                    span {
                        font-size: 24px;
                        &:first-child {
                            color: #333;
                            margin-right: 100px;
                            img {
                                width: 44px;
                                height: 44px;
                                border-radius: 50%;
                                margin-right: 10px;
                                vertical-align: middle;
                                overflow: hidden;
                            }
                        }
                        &:last-child {
                            color: #666;
                            i {
                                color: #666;
                                font-size: 40px;
                                vertical-align: middle;
                            }
                        }
                    }
                    >i {
                        float: right;
                        margin: 20px 0;
                        color: #999;
                        font-size: 36px;
                        margin-left: 32px;
                    }
                }
            }
            .empty {
                margin-top: 100px;
            }
        }
    }
</style>

3、js

<script>
import defaultAvatar from "@/assets/images/avatar.png";
import CareCell from '@/components/find/CareCell';

export default {
    name: "FindHomePage",
    components: {
        CareCell
    },
    data() {
        return {
      defaultAvatar: `onerror=null;src='${defaultAvatar}'`,
            tabList: [],
            activetab: 0,
            bgStyle: {
        // 设置初始状态是透明的
        background: "rgba(55, 69, 110, 0)"
            },
            tabFixed: false,
            isSelf: true,
            url: "/article/getUserArticleList",
            list: [],
            username: "",
            params: {},
            userInfo: {}
        }
    },
    created() {
        // 判断是否是用户本人主页
        if (this.$store.getters.getUserInfo.username == this.$route.query.username) {
            this.username = this.$store.getters.getUserInfo.username
            this.isSelf = true;
            this.tabList = [ 
                {
                    label: '我发布的',
                    num: 0
                },
                {
                    label: '我的草稿',
                    num: 0
                },
                {
                    label: '我喜欢的',
                    num: 0
                }
            ];
        } else {
            this.username = this.$route.query.username;
            this.isSelf = false;
            this.tabList = [ 
                {
                    label: 'TA的发布',
                    num: 0
                },
                {
                    label: 'TA的喜欢',
                    num: 0
                }
            ];
        }

        this.params = {
            viewUsername: this.username,
            status: this.isSelf ? 1 : 2
        }
    },
    mounted() {
        this.getUserInfo();
        window.addEventListener("scroll", this.handleScroll);
    },
    methods: {
        getUserInfo() {
            this.$_api.find.userInfo(this.username).then(res => {
                const result = this.$_api.result(res);
                if (this.$_api.successful(result)) {
                    this.userInfo = result.data;
                } else {
                    this.$toast(this.$_api.msg(result));
                }
            })
        },
        changeTab(index) {
            if (this.activetab == index) return;
            this.activetab = index;
            if (index === 0) {
                this.params = {
                    viewUsername: this.username,
                    status: this.isSelf ? 1 : 2
                }
                this.url = "/article/getUserArticleList";
            } else if (index == 2) {
                this.params = {
                    viewUsername: this.username
                }
                this.url = "/article/getUserLikeArticleList";
            } else {
                this.params = {
                    viewUsername: this.username
                }
                if (this.isSelf) {
                    this.params.status = 0
                }
                this.url = this.isSelf ? "/article/getUserArticleList" : "/article/getUserLikeArticleList"
            }
            this.$refs.list.reset();
        },

        goFriendList(type) {
            if (!this.isSelf) return;
            this.$router.push({ name: 'FindFriendList', query: { type: type }})
        },

        delArticle(row) {
            this.$dialog.confirm({
                title: '提示',
                message: '确认删除该草稿吗?'
            }).then(() => {
                // on confirm
            })
        },
        editArticle(row) {
            this.$store.commit("IS_RESET_STATE", 1);
            this.$router.push({ 
                name: 'PublishShare',
                query: {
                    articleId: row.id
                }
            });
        },  

    onGetdata(data) {
      this.list = data.map(item => {
                item.picArr = item.pics.split(",");
                return item;
            })
    },

        // 关注-取消关注
        clickCare() {
            if (this.userInfo.isFollow) { // 删除关注
                this.$_api.find.deleteUserFollow(this.username).then(res => {
                    const result = this.$_api.result(res);
                    if (this.$_api.successful(result)) {
                        this.getUserInfo();
                    } else {
                        this.$toast(this.$_api.msg(result));
                    }
                })
            } else { // 添加关注
                this.$_api.find.addUserFollow(this.username).then(res => {
                    const result = this.$_api.result(res);
                    if (this.$_api.successful(result)) {
                        this.getUserInfo();
                    } else {
                        this.$toast(this.$_api.msg(result));
                    }
                })
            }
        },

        handleScroll () {
        //获取当前页面的滚动条纵坐标位置 网页被卷去的高
            const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; 
            let opacity = scrollTop / 140;
            opacity = opacity > 1 ? 1 : opacity;
            this.bgStyle = { background: `rgba(55, 69, 110, ${ opacity })`};
            
            // tab滚动到页面顶部时固定在顶部(header下面)
            let offsetHeight = document.querySelector('#topWrap').offsetHeight;
            let fz = document.documentElement.style.fontSize; // 获取根元素的字体大小
            let scaleNum = 75 / parseFloat(fz); // 计算px转成rem的基数
            // 判断 滚动的高度 >= top盒子的高度 - (header的高度 + tab栏的高度)
            this.tabFixed = scrollTop * scaleNum >= offsetHeight * scaleNum - 188 ? true : false;
    },

        turnPage() {
            this.$store.commit("IS_RESET_STATE", 1);
            this.$router.push({ name: 'PublishShare' });
        }
    },
    destroyed() {
        window.removeEventListener("scroll", this.handleScroll);
    }
}
</script>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容