vue3 header 追随 affix を いい感じに

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;
}


```


以上です