jee*_*rbl 35 javascript vue.js vuejs2
我想听听Vue组件中的窗口滚动事件.这是我到目前为止尝试的内容:
<my-component v-on:scroll="scrollFunction">
...
</my-component>
Run Code Online (Sandbox Code Playgroud)
随着scrollFunction(event)
正在我的组件方法来定义,但它似乎并没有工作.
任何人都知道如何做到这一点?
谢谢!
jee*_*rbl 92
其实我找到了解决方案.我在scroll
创建组件时在事件上添加了一个事件监听器.此外,请确保在销毁组件时删除事件侦听器.
export default {
methods: {
handleScroll (event) {
// Any code to be executed when the window is scrolled
}
},
created () {
window.addEventListener('scroll', this.handleScroll);
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll);
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
我多次需要此功能,因此我已将其提取到mixin 中。它可以像这样使用:
import windowScrollPosition from 'path/to/mixin.js'
new Vue({
mixins: [ windowScrollPosition('position') ]
})
Run Code Online (Sandbox Code Playgroud)
这会position
在 Vue 实例上创建一个响应式属性(可以随意命名)。该属性包含作为[x,y]
数组的窗口滚动位置。
随意使用这个 CodeSandbox 演示。
这是mixin的代码。它经过了彻底的评论,因此了解它的工作原理应该不会太难:
function windowScrollPosition(propertyName) {
return {
data() {
return {
// Initialize scroll position at [0, 0]
[propertyName]: [0, 0]
}
},
created() {
// Only execute this code on the client side, server sticks to [0, 0]
if (!this.$isServer) {
this._scrollListener = () => {
// window.pageX/YOffset is equivalent to window.scrollX/Y, but works in IE
// We round values because high-DPI devies can provide some really nasty subpixel values
this[propertyName] = [
Math.round(window.pageXOffset),
Math.round(window.pageYOffset)
]
}
// Call listener once to detect initial position
this._scrollListener()
// When scrolling, update the position
window.addEventListener('scroll', this._scrollListener)
}
},
beforeDestroy() {
// Detach the listener when the component is gone
window.removeEventListener('scroll', this._scrollListener)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题,但我找到了Vue.js 2.0+ 自定义指令的更好解决方案:我也需要绑定滚动事件,然后我实现了这个。
首先,使用@vue/cli
,将自定义指令添加到src/main.js
(在 Vue.js 实例之前)或您启动它的任何地方:
Vue.directive('scroll', {
inserted: function(el, binding) {
let f = function(evt) {
if (binding.value(evt, el)) {
window.removeEventListener('scroll', f);
}
}
window.addEventListener('scroll', f);
}
});
Run Code Online (Sandbox Code Playgroud)
然后,将自定义v-scroll
指令添加到要绑定的元素和/或组件。当然你必须插入一个专用的方法:我handleScroll
在我的例子中使用过。
<my-component v-scroll="handleScroll"></my-component>
Run Code Online (Sandbox Code Playgroud)
最后,将您的方法添加到组件中。
methods: {
handleScroll: function() {
// your logic here
}
}
Run Code Online (Sandbox Code Playgroud)
在这里您不必再关心 Vue.js 生命周期,因为自定义指令本身就是如此。
您的要求是在组件上,但是最后增加了主体,而不是组件。当然,您也可以在特定元素上执行此操作,但是,嘿...这就是直接与Vue自定义组件一起使用的功能。
<MyCustomComponent nativeOnScroll={this.handleScroll}>
Run Code Online (Sandbox Code Playgroud)
要么
<my-component v-on:scroll.native="handleScroll">
Run Code Online (Sandbox Code Playgroud)
并为handleScroll定义一个方法。简单!
小智 6
我认为最好的方法是添加“.passive”
v-on:scroll.passive='handleScroll'
Run Code Online (Sandbox Code Playgroud)
In my experience, using an event listener on scroll can create a lot of noise due to piping into that event stream, which can cause performance issues if you are executing a bulky handleScroll
function.
I often use the technique shown here in the highest rated answer, but I add debounce on top of it, usually about 100ms
yields good performance to UX ratio.
Here is an example using the top-rated answer with Lodash debounce added:
import debounce from 'lodash/debounce';
export default {
methods: {
handleScroll(event) {
// Any code to be executed when the window is scrolled
this.isUserScrolling = (window.scrollY > 0);
console.log('calling handleScroll');
}
},
created() {
this.handleDebouncedScroll = debounce(this.handleScroll, 100);
window.addEventListener('scroll', this.handleDebouncedScroll);
},
beforeDestroy() {
// I switched the example from `destroyed` to `beforeDestroy`
// to exercise your mind a bit. This lifecycle method works too.
window.removeEventListener('scroll', this.handleDebouncedScroll);
}
}
Run Code Online (Sandbox Code Playgroud)
Try changing the value of 100
to 0
and 1000
so you can see the difference in how/when handleScroll
is called.
BONUS: You can also accomplish this in an even more concise and reuseable manner with a library like vue-scroll
. It is a great use case for you to learn about custom directives in Vue if you haven't seen those yet. Check out https://github.com/wangpin34/vue-scroll.
This is also a great tutorial by Sarah Drasner in the Vue docs: https://vuejs.org/v2/cookbook/creating-custom-scroll-directives.html
归档时间: |
|
查看次数: |
47376 次 |
最近记录: |