Vue acting weird with condition relating to window width

Viewed 110

So I am just trying to get my basic Vue navbar functions working such as changing class on scroll (which works fine) and changing class on resize, which I'm having a bit more trouble with.

Here is the content of my <template> tags:

  <nav class="navbar is-fixed-top navbar-max">
    {{windowWidth}}
  </nav> 

...and the relevant content of my <script> tags:

export default {
  name: "Navbar",
  data () {
    return {
      windowWidth: window.innerWidth
    } 
  },
  created () {
    window.addEventListener('resize', this.onResize);
  },
  mounted () {
    this.windowWidth = window.innerWidth
  },
  beforeDestroy () {
    window.removeEventListener('resize', this.onResize); 
  },
  methods: {
    onResize() {
      let navbar = document.querySelector(".navbar");

      if (this.windowWidth > 768) {
        console.log(this.windowWidth),
        navbar.classList.remove("nav-mobile"),
        navbar.classList.add("nav-desktop")
      }
      else {
        console.log(this.windowWidth),
        navbar.classList.remove("nav-desktop"),
        navbar.classList.add("nav-mobile")
      }
    }
  }
}

My issue is really odd - all my console.log()'s output the correct width, and so does {{windowWidth}} in the navbar, and even the adding and removing classes works! It's just that the changed classes don't seem to have any effect until windowWidth = 1024 and I have no idea why...

Any help?

Cheers :)

1 Answers

You never set this.windowWidth after mount.

Simply add the following:

onResize() {
    this.windowWidth = window.innerWidth // add this line
    ...
}

I would also like to point out that what it looks like you're trying to achieve (different nav-bar-styling on mobile and desktop) is very doable without any vue-/js-magic using CSS @media-queries.

And if you still wish to do it with vue, you should do it the vue way: Make a computed method like so:

computed: {
  isMobile() {
    return this.windowWidth <= 768
  }
}

and then update the class directly on the nav-tag using class-binding.

Related