レイアウトを使用しているときのコンポーネントの渡し方がわからなかったので、その備忘録。
nuxt@2.15.8
node: '16.2.0'
macOS M2 Ventura 13.3.1
Nuxt.jsで簡単なWebサイトを制作。
ヘッダーの機能はTheHeader.vue
にまとめましたが、今回はたまたまあるページにはヘッダーを載せたくないという与件があったため、footerが全ページに配置されているlayouts/default.vue とは別にlayouts/childlayout.vueを作成し、そのレイアウトを通してコンポーネントTheHeader.vue
> TheBurger.vue
の順に値(ハンバーガーメニューのトグルtrue/false)をバケツリレーすることにしました。
TheHeader.vue
<template>
<header id="header" class="header">
<NuxtLink to="/"
><img class="logo_pi" src="~/assets/img/logo.png" alt="header logo"
/></NuxtLink>
<nav>省略</nav>
<TheBurger :active="active" @toggle-menu="toggleActive"></TheBurger>
</header>
</template>
<script>
export default {
props: {
active: {
type: Boolean,
required: true,
default: true,
},
},
methods: {
toggleActive() {
this.$emit('toggle-menu')
},
},
}
</script>
TheBurger.vue
<template>
<div
id="burger"
:class="{
active: active,
}"
@click="toggleActive"
>
<button type="button" class="burger_button" title="Menu">
<span class="burger_bar burger_bar__1"></span>
<span class="burger_bar burger_bar__2"></span>
</button>
<div v-show="active" class="navbarNav">
<div class="wrapper">
<NuxtLink to="/"
><img
class="logo_pi__white"
src="~/assets/img/logo_white.png"
alt="header logo white"
/></NuxtLink>
<nav class="navbar_nav">省略</nav>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TheBurger',
props: {
active: {
type: Boolean,
required: true,
default: false,
},
},
methods: {
toggleActive() {
this.$emit('toggle-menu')
},
},
}
</script>
childlayout.vue
<template>
<div>
<TheHeader :active="menuActive" @toggle-menu="toggleMenu"></TheHeader>
<Nuxt />
<CookieControl locale="ja"></CookieControl>
<TheFooter />
</div>
</template>
<script>
export default {
data() {
return {
menuActive: false, // valiables for controling the menu
}
},
created() {
this.setToggleListerer()
},
methods: {
setToggleListerer() {
this.$on('toggle-menu', () => {
this.toggleMenu()
})
},
toggleMenu() {
this.menuActive = !this.menuActive
},
},
}
</script>
参考にした記事はこちら
【Nuxt.js】layoutsに設定をまとめつつ、タイトルはpagesから設定したい
実装方法が古かったのと、(レイアウトを使っている)ページからのmountedは不要だったので、上記コードではその部分を省略しています。