Reputation: 4165
I've started to use Vue CLI but ran into a problem of handling window scroll position.
Just copied this example from Vue docs but it doesn't work.
This is my Nav.vue
component:
<template>
<nav v-scroll="handleScroll"></nav>
</template>
<script>
export default {
name: 'my-nav',
data() {
return {
scrolled: false
}
},
directives: {
scroll: {
inserted: function (el, binding) {
let f = function (evt) {
if (binding.value(evt, el)) {
window.removeEventListener('scroll', f)
}
}
}
}
},
methods: {
handleScroll: function (evt, el) {
if (window.scrollY > 50) {
el.setAttribute(
'style',
'opacity: .5; background-color: red;'
)
}
return window.scrollY > 100
}
}
}
</script>
<style lang="scss" scoped>
nav {
position: fixed;
width: 100%;
height: 68px;
background-color: white;
z-index: 100;
}
</style>
An error occurs in this case:
error in ./src/components/Nav.vue
Module Error (from ./node_modules/eslint-loader/index.js):
error: 'f' is assigned a value but never used (no-unused-vars)
Also I searched other approaches how to handle scroll event but none of the worked.
In this case handleScroll
method is just ignored:
<template>
<nav v-bind:class="{ hidden: scrolled}"></nav>
</template>
<script>
export default {
name: 'my-nav',
data() {
return {
scrolled: false
}
},
methods: {
handleScroll: function () {
this.scrolled = window.scrollY > 150;
}
},
created: function () {
window.addEventListener('scroll', this.handleScroll);
},
destroyed: function () {
window.removeEventListener('scroll', this.handleScroll);
}
}
</script>
<style>
.hidden {
opacity: .3;
}
</style>
It seemed to me that such simple things are much easier to resolve with Vue but I was wrong.
How to make scroll event work properly?
Upvotes: 0
Views: 370
Reputation: 66093
Your second approach should work, with one little caveat: you are not setting scrolled
in the component data properly: you should be using this.scrolled
, i.e.:
handleScroll: function () {
this.scrolled = window.scrollY > 150;
}
See proof-of-concept example:
new Vue({
el: '#app',
data() {
return {
scrolled: false
}
},
methods: {
handleScroll: function() {
this.scrolled = window.scrollY > 150;
}
},
created: function() {
window.addEventListener('scroll', this.handleScroll);
},
destroyed: function() {
window.removeEventListener('scroll', this.handleScroll);
}
});
body {
min-height: 200vh;
}
nav {
position: fixed;
top: 20px;
left: 20px;
}
.hidden {
opacity: 0.3
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<nav v-bind:class="{ hidden: scrolled }">NAV</nav>
</div>
Upvotes: 1