Nuxt / Vue / Bootstrap-vue缩小滚动导航栏

时间:2018-07-27 18:01:26

标签: vue.js vuejs2 nuxt.js bootstrap-vue

通过Nuxt学习Vue。要根据页面滚动位置更改导航栏类。

已在several places中找到,但找不到有效的解决方案。

这就是我要处理的东西:

``` default.vue
<template lang="pug">
div(v-on:scroll="shrinkNav", v-on:click="shrinkNav")
  b-navbar.text-center(toggleable="sm" type="light" sticky v-b-scrollspy)
    #myNav.mx-auto.bg-white
      b-navbar-toggle(target="nav_collapse")
      b-navbar-brand.mx-auto(href="#") 
        | Example.org
      b-collapse#nav_collapse.mx-auto(is-nav='')
        b-navbar-nav(justified, style="min-width: 600px").vertical-center
          b-nav-item.my-auto(href='#home') Home
          b-nav-item.my-auto(href='/how') How
          i.fab.fa-earlybirds.fa-2x.mt-2.mb-3
          b-nav-item.my-auto(href='/values') Values
          b-nav-item.my-auto(href='/join-us') Join Us
  #content.container(v-on:scroll="shrinkNav", v-on:click="shrinkNav")
nuxt
    nuxt
</template>

<script>
  // resize navbar on scroll
  export default {
    methods: {
      shrinkNav() {
        var nav = document.getElementById('nav')
        var content = document.getElementById('content')
        if (nav && content) {
          if(content.scrollTop >= 150) {
            nav.classList.add('shrink')
          } else {
            nav.classList.remove('shrink')
          }
        }
        console.log(document.documentElement.scrollTop || document.body.scrollTop)
      }      
    }
  }
</script>
```

shrinkNav在单击时运行两次,但在滚动时没有任何运行。 Vue / Nuxt执行此操作的方法是什么?

2 个答案:

答案 0 :(得分:1)

在您的 .vue 中:

<template>部分:

<nav id="nav" class="navbar is-transparent is-fixed-top">

<script>部分:

export default {
mounted() {
      this.$nextTick(function(){
        window.addEventListener("scroll", function(){
          var navbar = document.getElementById("nav")
          var nav_classes = navbar.classList
          if(document.documentElement.scrollTop >= 150) {
            if (nav_classes.contains("shrink") === false) {
              nav_classes.toggle("shrink");
            }
          }
          else {
            if (nav_classes.contains("shrink") === true) {
              nav_classes.toggle("shrink");
            }
          }
        })
      })
    },
}

Live Demo on codesandbox

答案 1 :(得分:0)

好的,这是使用插件的解决方案。可能有更好的方法:

1)在plugins/scroll.js

中定义一条指令
``` javascript
// https://vuejs.org/v2/cookbook/creating-custom-scroll-directives.html#Base-Example
import Vue from 'vue'

Vue.directive('scroll', {
  inserted: function (el, binding) {
    let f = function (evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f)
      }
    }
    window.addEventListener('scroll', f)
  }
})
```

2)将插件添加到nuxt.config.js的项目中

``` javascript
module.exports = {
  head: { },
  plugins: [
    { src: '~/plugins/scroll.js', },
  ]
}
```

3)使用v-scroll指令在/layouts/default.vue的菜单中定义自定义行为

``` javascript
<template lang="pug">
div(v-scroll="shrinkNav")
  b-navbar.text-center(toggleable="sm" type="light" sticky)
    #myNav.mx-auto.bg-white
      b-navbar-toggle(target="nav_collapse")
      b-navbar-brand.mx-auto(href="/#home") Example.org
      b-collapse#nav_collapse.mx-auto(is-nav='')
        b-navbar-nav(justified, style="min-width: 600px").vertical-center
          b-nav-item.my-auto(to='/#home') Home
  #content.container
    nuxt
</template>

<script>
  export default {
    methods: {
      shrinkNav() {
        var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop
        var nav = document.getElementById('myNav')
        console.log(scrollPosition, nav)
        if(scrollPosition >= 150) {
          nav.classList.add('shrink')
        } else {
          nav.classList.remove('shrink')
        }
      },
    },
  }
</script>

<style>
  nav.navbar {
    margin: 0;
    padding: 0;
  }
  #myNav {
    border-radius: 0 0 10px 10px;
    border: 2px solid purple;
    border-top: none;
  }
  #myNav.shrink {
    border: none;
  }
</style>
```