Vue router を2ページで使用しています:
let routes = [
{
path: '/',
component: require('./components/HomeView.vue')
},
{
path: '/intro',
component: require('./components/IntroView.vue')
}
]
これはうまく機能しますが、私のコンポーネントにはそれぞれ異なるボディスタイルがあります。
HomeView.vue:
<template>
<p>This is the home page!</p>
</template>
<script>
export default {
}
</script>
<style>
body {
background: red;
}
</style>
IntroView.vue:
<template>
<div>
<h1>Introduction</h1>
</div>
</template>
<script>
export default {
}
</script>
<style>
body {
background: pink;
}
</style>
私の目標は、これら2つのページに異なるバックグラウンドスタイルを持たせることです(最終的にはそれらの間で移行します)。しかし、home
ルート(red
背景付き)に移動して、intro
ルートをクリックすると、背景色はred
( pink
)に変更してほしい。
編集:index.html:
<body>
<div id="app">
<router-link to="/" exact>Home</router-link>
<router-link to="/intro">Introduction</router-link>
<router-view></router-view>
</div>
<script src="/dist/build.js"></script>
</body>
lifecycle hookbeforeCreate
とグローバルスタイルシートで動作するようにしました。 global.css
:
body.home {
background: red;
}
body.intro {
background: pink;
}
の中に <script>
セクションのHomeView.vue
:
export default {
beforeCreate: function() {
document.body.className = 'home';
}
}
IntroView.vue
。
または、これを使用できます
Vue-routerを使用してページ本体クラスを制御できます。同様の問題に直面したときにこれを書いた。また、 コンポーネントがクリックされたときにボディにクラスを追加しますか? も参照します。
watch: {
$route: {
handler (to, from) {
const body = document.getElementsByTagName('body')[0];
if (from !== undefined) {
body.classList.remove('page--' + from.name.toLowerCase());
}
body.classList.add('page--' + to.name.toLowerCase());
},
immediate: true,
}
},
別の非常に単純なソリューションで、ベースのApp.vueファイルに追加します。 to.nameをto.meta.classまたはより具体的なものに似たものに置き換えることができます。これは一度すればいいのですが、型ソリューションは永遠に動作します。
特定のルートで#app
コンテナと一緒にhtml
およびbody
タグのスタイルを変更したいときに問題に遭遇しました。 、これは非常に複雑になる可能性があります。
読んだ後:
あなたのApp.vue(集中状態と見なすことができます):
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'my-app',
methods: {
handleStyles () {
// Red style to the body tag for the home page
if (['/'].includes(this.$route.path)) document.body.className = 'bg-red'
// Pink style to the body tag for all other pages
else if (document.body.classList.contains('bg-red')) document.body.className = 'bg-pink'
}
},
// Handle styles when the app is initially loaded
mounted () {
this.handleStyles()
},
// Handle styles when the route changes
watch: {
'$route' () {
this.handleStyles()
}
}
}
</script>
<style>
.bg-red {
background: red;
}
.bg-pink {
background: pink;
}
</style>
そのため、ルート/
には赤のスタイルが適用され、他のすべてのルートにはピンクのスタイルが適用されます。
handleStyles
ロジックはbeforeCreated
フックで処理できますが、私の場合、これはhtml
およびbody
スタイルにのみ影響しますが、#app
ルータービューがレンダリングされる要素は、domがマウントされている場合にのみ使用できるため、少し拡張性の高いソリューションだと思います。
クラスがビュー固有の場合、これが役立つかもしれません
methods: {
toggleBodyClass(addRemoveClass, className) {
const el = document.body;
if (addRemoveClass === 'addClass') {
el.classList.add(className);
} else {
el.classList.remove(className);
}
},
},
mounted() {
this.toggleBodyClass('addClass', 'mb-0');
},
destroyed() {
this.toggleBodyClass('removeClass', 'mb-0');
},
methods
セクションをmixinに移動すると、コードはDRYになります。
afterEach
フックを使用して、ルーターファイルで直接行うこともできます。
mainRouter.afterEach((to) => {
if (["dialogs", "snippets"].includes(to.name)) {
document.body.style.backgroundColor = "#F7F7F7";
// or document.body.classList.add(className);
} else {
document.body.style.backgroundColor = "#FFFFFF";
// or document.body.classList.remove(className);
}
});
to
は、ルート名(名前が付いている場合)、パスなどを含むルートオブジェクトです。 すべての小道具のドキュメント
Style要素でscoped属性を使用できます。次に、スタイルはそのvueファイルにのみ制限されます。
HomeView.vue:
<template>
<p>This is the home page!</p>
</template>
<script>
export default {
}
</script>
<style scoped>
body {
background: red;
}
</style>
IntroView.vue:
<template>
<div>
<h1>Introduction</h1>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
body {
background: pink;
}
</style>