我使用Vue router两页:
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>
我的目标是让这两个页面具有不同的背景样式(最终在它们之间进行过渡)。但是当我转到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>
答案 0 :(得分:25)
我使用了lifecycle hook beforeCreate
和全局样式表。在global.css
:
body.home {
background: red;
}
body.intro {
background: pink;
}
<script>
的{{1}}部分:
HomeView.vue
在export default {
beforeCreate: function() {
document.body.className = 'home';
}
}
中类似。
答案 1 :(得分:3)
或者你可以使用这个
它允许使用vue-router控制页面体类。 在遇到类似问题时写到这一点。 它还指Add a class to body when component is clicked?
答案 2 :(得分:1)
当我想在特定路线上修改engines
和package.json
标签以及html
容器的样式时遇到了一个问题,我发现这是针对各种原因,这可能非常复杂。
通读后:
在您的 App.vue 中(可以视为集中状态):
body
因此,对于路线#app
,您将获得红色样式;对于所有其他路线,将获得粉红色样式。
<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
样式,而{{1 }}渲染路由器视图的元素只有在安装了dom后才可用,因此我认为这是一个稍微扩展一些的解决方案。
答案 3 :(得分:1)
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或类似名称,以实现更具体的功能。这样做一次很不错,但是它永远可以解决类型问题。
答案 4 :(得分:0)
如果该类是特定于视图的,可能会有所帮助
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,然后将代码干燥即可。
答案 5 :(得分:0)
您也可以使用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
是一个路由对象,其中包含路由名称(如果已命名),路径等。Documentation for all the props
答案 6 :(得分:0)
您可以在样式元素中使用范围属性。然后,样式将仅限于该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>