LoginSignup
0
0

vue3 header 追随 affix を いい感じに

Last updated at Posted at 2022-01-24

vue2の時は vueheader という良いライブラリがあったが、
vue3では見当たらない。

今回やりたいことは、以下2点

・ヘッダメニューの追随
・上に少しでもスクロールした場合はヘッダメニューを自動的に隠す

ということで実装

追記

フッダも同様にやりたいので、まとめておく

app.scss

header {
    width: 100%; /* 幅いっぱいを指定 */
    height: 50px; /* 高さを50pxに指定 */
    background: #CCC; /* 背景色にグレーを指定 */
    padding: 20px 50px; /* ヘッダーに上下左右それぞれ余白を指定 */
    box-sizing: border-box; /* padding分を含んで幅を100%にするため */
    position: fixed; /* ウィンドウを基準に画面に固定 */
    top: 0; /* 上下の固定位置を上から0pxにする */
    left: 0; /* 左右の固定位置を左から0pxにする */
    align-items: center; /* 中の要素を上下中央に並べる */
    z-index:9999;/* 重なり順を最前面へ */
}

.headerHide {
    display:none;
}

footer {
    width: 100%; /* 幅いっぱいを指定 */
    height: 50px; /* 高さを50pxに指定 */
    background: #CCC; /* 背景色にグレーを指定 */
    padding: 20px 50px; /* ヘッダーに上下左右それぞれ余白を指定 */
    box-sizing: border-box; /* padding分を含んで幅を100%にするため */
    position: fixed; /* ウィンドウを基準に画面に固定 */
    bottom: 0; /* 上下の固定位置を上から0pxにする */
    left: 0; /* 左右の固定位置を左から0pxにする */
    align-items: center; /* 中の要素を上下中央に並べる */
    z-index:9999;/* 重なり順を最前面へ */
}

.footerHide {
    display:none;
}

app.vue
<template>

    <header :class="{ headerHide: scroll.headerHide}">
        <div>
            <RouterLink :to="{ path: '/'}">
                <el-button type="primary">トップへ</el-button>
            </RouterLink>
        </div>
    </header>

    <router-view></router-view>

    <footer :class="{ footerHide: scroll.footerHide}">
        <div style="background-color: #ededed;">
            bottom
        </div>
    </footer>


</template>
<script lang="ts" setup>
const scroll = ref({
  Y: 0,
  beforeY: 0,
  headerHide: false,
  footerHide: false,
});

const handleScroll = () => {
  scroll.value.beforeY = scroll.value.Y; // 以前のスクロールを保存
  scroll.value.Y = window.scrollY;

  if (scroll.value.Y < scroll.value.beforeY) {
    console.log("上に戻りました");
    scroll.value.headerHide = false;
  } else {
    scroll.value.headerHide = true;
  }
};

window.addEventListener("scroll", handleScroll);
</script>

ここまで。コピペで動く。
以下は古い情報。

app.js

    const app = createApp({

        data () {
            return {
                scroll:{
                    Y:0,
                    beforeY:0,
                    hide:false
                },
            }
        },

        mounted() {
            window.addEventListener('scroll', this.handleScroll);
        },



        methods: {

            handleScroll() {
                this.scroll.beforeY = this.scroll.Y;//以前のスクロールを保存
                this.scroll.Y = window.scrollY;

                if(this.scroll.Y < this.scroll.beforeY){
                    console.log("上に戻りました");
                    this.scroll.hide = false;
                } else {
                    this.scroll.hide = true;
                }
            },

        }

    });


vue.blade.php

<header :class="{ headerHide: scroll.hide}">
    ここにメニューとか入れる
</header>

もしくは、最新の場合は以下のような感じで。

App.vue
<script lang="ts" setup>
const scroll = ref({
    Y:0,
    beforeY:0,
    hide:false
})

function handleScroll() {
    scroll.value.beforeY = scroll.value.Y; // 以前のスクロールを保存
    scroll.value.Y = window.scrollY;

    if (scroll.value.Y < scroll.value.beforeY) {
        console.log("上に戻りました");
        scroll.value.hide = false;
    } else {
        scroll.value.hide = true;
    }

}

window.addEventListener('scroll', handleScroll);
</script>

app.scss

header {
    width: 100%; /* 幅いっぱいを指定 */
    height: 50px; /* 高さを50pxに指定 */
    background: #CCC; /* 背景色にグレーを指定 */
    padding: 20px 50px; /* ヘッダーに上下左右それぞれ余白を指定 */
    box-sizing: border-box; /* padding分を含んで幅を100%にするため */
    position: fixed; /* ウィンドウを基準に画面に固定 */
    top: 0; /* 上下の固定位置を上から0pxにする */
    left: 0; /* 左右の固定位置を左から0pxにする */
    align-items: center; /* 中の要素を上下中央に並べる */
    z-index:9999;/* 重なり順を最前面へ */
}

.headerHide {
    display:none;
}


以上です

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0