Skip to content Skip to sidebar Skip to footer

Changing Body Styles In Vue Router

I'm using Vue router with two pages: let routes = [ { path: '/', component: require('./components/HomeView.vue') }, { path: '/intro', co

Solution 1:

I got it working with the lifecycle hookbeforeCreate and a global stylesheet. In global.css:

body.home {
    background: red;
}
body.intro {
    background: pink;
}

In the <script> section of HomeView.vue:

exportdefault {
    beforeCreate: function() {
        document.body.className = 'home';
    }
}

And similar in IntroView.vue.

Solution 2:

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

Another fairly simple solution, add it to your base App.vue file. The to.name can be replaced with to.meta.class or similar for something more specific. This is a nice do it once and it works forever type solution though.

Solution 3:

Alternatively you can use this

It allows to control your page body classes with vue-router. Wrote this when faced the similar issue. It also refers to Add a class to body when component is clicked?

Solution 4:

If the class is view specific, may be this will help

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');
},

Move the methods section to a mixin and then the code can be DRY.

Solution 5:

I ran into an issue when I wanted to modify the styles of the html and body tags along with the #app container on specific routes and what I found out is that for various reasons, this can be quite complicated.

After reading through:

In your App.vue (could be considered as the centralised state):

<template><divid="app"><router-view></router-view></div></template><script>exportdefault {
    name: 'my-app',
    methods: {
      handleStyles () {
        // Red style to the body tag for the home pageif (['/'].includes(this.$route.path)) document.body.className = 'bg-red'// Pink style to the body tag for all other pageselseif (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 changeswatch: {
      '$route' () {
        this.handleStyles()
      }
    }
  }
</script><style>.bg-red {
    background: red;
  }
  .bg-pink {
    background: pink;
  }
</style>

So for the route / you get the red style and for all other routes the pink style is applied.

The handleStyles logic could have been dealt with by the beforeCreated hook however in my case, this would only affect the html and body styles but the #app element where the router view is rendered into would only available when the dom has been mounted so I think that it is a slightly more extensible solution.

Post a Comment for "Changing Body Styles In Vue Router"