简体   繁体   中英

How do I add a body class when a Vue Component is in the viewport?

Is there a way that I can add a class, maybe to the body tag, when a user clicks on a router link. Then remove this class again when they leave the view?

The reason being is that for the app shell I have a fixed header & footer. All views (Vue Components) feature these two elements as part of the design, except just one page where these two elements need removing.

I figured that if I could add a body class dynamically, I could then add the below CSS. Can this be done?

.minimal-shell .header,
.minimal-shell .footer{
    display:none;
}

I'm on mobile so I apologize for formatting. You can just provide a class based on a prop.

<body class="[isInView ? 'view-class' : '']">
 <Linker @click="goToView" />
</body>

Model:

data: function() {
return {
  isInView: false;
}
},
methods: {
  ... ,
 goToView() {
   this.isInView = true;
   this.$router.push({ path: 'view' });
 }
 }

There are several ways to do what you are asking, as you can imagine.

1. Vue-Router Hooks

When you navigate to route components (components you render inside <router-view> ) these components will have special router lifecycle-hooks you can use:

beforeRouteEnter (to, from, next) {
    getPost(to.params.id, (err, post) => {
      next(vm => vm.setData(err, post))
    })
  },
  // when route changes and this component is already rendered,
  // the logic will be slightly different.
  beforeRouteUpdate (to, from, next) {
    this.post = null
    getPost(to.params.id, (err, post) => {
      this.setData(err, post)
      next()
    })
  },

More about this in the official documentation

2. Vue-Router navigation guards

You could also use navigation guards - a function that is called at a certain point during a route navigation:

router.beforeEach((to, from, next) => {
  // ...
})

More about this also in the official documentation

3. Explicit, component-specific action

Of course, you can also trigger all changes you want in the components itself. Either in the components you navigate to - or a root component for your <router-view> . My first idea would be to handle the logic in a watcher :

watch: {
  $route: {
    immediate: true, // also trigger handler on initial value
    handler(newRoute) {
      if (newRoute.params.myParam === 'my-param') {
        document.body.classList.add('my-class');
      }
    }
  }   
}

I personally would watch the route in a root layout-component as I like to keep naviation guards for business logic / authentication (not style).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM