У меня есть очень простое приложение, состоящее из 2 компонентов: App.vue и другого компонента Home.vue, в котором я храню остальную часть структуры приложения: липкий заголовок и несколько разделов с якорями для прокрутки.
Я хочу применить класс к липкому заголовку, чтобы свернуть логотип во время прокрутки страницы. Поэтому я подумал, что буду следить за любыми изменениями в window.scrollY. Поэтому, если scrollY больше 0, примените класс, который минимизирует логотип.
Я пытался прослушивать события прокрутки в своем компоненте, но это не зашло слишком далеко. В этом обсуждении здесь представлено очень хорошее решение, но я не знаю, где разместить событие прокрутки. https://github.com/vuejs/Обсуждение/issues/324
Итак, я подумал, что наиболее подходящим решением будет создать свойство данных, присвоить ему число window.scrollY и затем следить за изменениями его значения. К сожалению, наблюдатель никогда не срабатывает. Так что теперь я застрял. Код:
data () {
return {
...
windowTop: window.top.scrollY
}
}
...
watch: {
windowTop: {
immediate: true,
handler (newVal, oldVal) {
console.info(newVal, oldVal);
},
}
}
Любые идеи о том, что я могу делать неправильно?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


window свойства нельзя использовать реактивно таким образом. Вместо этого вам нужно будет прослушать событие windowscroll и ответить соответствующим образом:
mounted() {
window.addEventListener("scroll", this.onScroll)
},
beforeDestroy() {
window.removeEventListener("scroll", this.onScroll)
},
methods: {
onScroll(e) {
this.windowTop = window.top.scrollY /* or: e.target.documentElement.scrollTop */
}
}
Вы можете использовать метод mounted(), чтобы добавить прослушиватель событий к объекту окна следующим образом:
var p = new Vue({
el: "#app",
data(){
return {
windowTop: 0
};
},
mounted()
{
var that = this;
window.addEventListener("scroll", function(){
that.windowTop = window.scrollY;
});
},
template: "<div style='height: 250vh'><div style='position: fixed; right: 0; top: 0'>{{windowTop}}</div></div>"
});<script src = "https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id = "app"></div>2020 Обновлено:
Используйте @scroll.passive для просмотра прокрутки любого элемента в компоненте:
Пример:
Шаблон
<div class = "room_message-stream" @scroll.passive = "handleScroll">
<ul class = "room_message-stream__list">
<li class = "room_message-stream__list-item">...</li>
</ul>
</div>
Методы:
handleScroll (e) {
var scrollPos = e.target.scrollTop
}
Для меня ничего из вышеперечисленного не сработало.
Мне пришлось передать true в качестве третьего параметра в прослушивателе добавления/удаления прокрутки:
mounted() {
window.addEventListener("scroll", this.onScroll, true)
},
beforeDestroy() {
window.removeEventListener("scroll", this.onScroll, true)
},
methods: {
onScroll(e) {
this.windowTop = e.target.scrollTop;
}
}
3-й параметр: У вас должна быть возможность подключить прослушиватель на уровне документа с третьим параметром true для захвата событий прокрутки для всех элементов. Вот как это выглядит:
document.addEventListener('scroll', function(e){ }, true);
Значение true в конце является важной частью, оно сообщает браузеру, что нужно захватить событие при отправке, даже если это событие обычно не всплывает, например изменение, фокус и прокрутка.
Я пытался сделать что-то, где мне просто нужно вызвать переменную или функцию, чтобы получить позицию прокрутки окна в любом компоненте. Поэтому, чтобы добиться этого, я в конечном итоге использую миксины. Вот мой код. Я использую нуст.
Внутри плагина создайте файл, например. прокрутка-position.js
import Vue from 'vue'
Vue.mixin({
data() {
return {
scrollPosition: window.scrollY
}
},
methods: {
get_scroll_position() {
window.addEventListener('scroll', () => {
this.scrollPosition = window.scrollY;
});
return this.scrollPosition
}
}
})
В nuxt.config.js
plugins:['@/plugins/scroll-position.js']
Теперь вы можете использовать get_scroll_position() в любом компоненте. Что-то вроде этого
:class = "{'header_sticky':get_scroll_position()>=80}"
scrollсобытия не могут бытьpreventDefaulted, поэтому флагpassiveздесь не поможет. Флаг обычно используется для улучшить производительность прокрутки для дорогостоящих обработчиков событийtouchstart/touchmove.