K7Buoy
K7Buoy

Reputation: 946

Apply classes to index.html in VueJs on events in components

I am using a BS4 template that applies classes to the <html> and <body> elements based on events on the page. I have trieddifferent techniques from the Vuejs Class and Style page here without success. I have also tried passing in the value as a prop from App.vue to the Sidebar which I have as a component.

This is where I have got to and the v-bind is not respecting the value at the root level.

In index.html

<body v-bind:class="{ sidebar-mini: this.$root.sidebarShrunk }">

In main.ts (entry point)

new Vue({
  data: {
    sidebarShrunk: false,
  },
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');

Updating the value as below does nothing, the class sidebar-mini is not applied.

Updating this value does nothing

EDIT

Thanks to the answers below - this is working - but a further question, is it the best way to do it or can it be refactored a little.

new Vue({
  data: {
    sidebarShrunk: false,
  },
  watch: {
    sidebarShrunk(sidebarShrunk) {
      if (sidebarShrunk) {
        document.body.classList.add('sidebar-mini');
      } else {
        document.body.classList.remove('sidebar-mini');
      }
    },
  },
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');

Upvotes: 0

Views: 824

Answers (1)

Jacob Goh
Jacob Goh

Reputation: 20855

Vue's syntax will only work on #app and its children, which apparently doesn't include the body element.

In a case like this, you can use watcher to set the body class using Vanilla Javascript.

  data: {
    sidebarShrunk: false,
  },
  watch:{
    sidebarShrunk: 
    {
      handler:function(value) {
        if(value)
          document.body.classList.add("sidebar-mini");
        else
          document.body.classList.remove("sidebar-mini");
      },
      immediate: true
    }
  },

demo: https://jsfiddle.net/jacobgoh101/xqLcuoav/5/

Upvotes: 2

Related Questions