我有一个布局如下的页面。
<template>
<v-container fluid class='pa-0 ma-0 assignment-container'>
<v-row class='pa-0 ma-0 gallery-bg'>
// ...v-img with height 60vh
</v-row>
<v-row class='pa-3'>
// ...row content
</v-row>
<v-row class='pa-3'>
// ... row content
</v-row>
<v-row
v-if='!works.length'
v-intersect='onIntersect'
class='pa-3 mt-4 flex-column'>
<v-row class='pa-3 ma-0'>
<h3 class='mb-4 acumin-semibold section-title section-title-h3'>
Works:
</h3>
</v-row>
<v-row class='pa-0 ma-0'>
<v-col
v-for='(skeleton, i) in skeletonCards'
:key='i'
xs='12'
sm='6'
md='4'
lg='3'>
<v-skeleton-loader
class='mx-auto'
max-width='374'
height='250'
type='card' />
</v-col>
</v-row>
</v-row>
<v-container v-else fluid>
<v-row class='pa-3 ma-0'>
<h3 class='mb-4 acumin-semibold section-title section-title-h3'>
Works:
</h3>
</v-row>
<v-row class='pa-0 ma-0'>
<v-col
v-for='work in works'
:key='work._id'
xs='12'
sm='6'
md='4'
lg='3'>
<WorkCard :assignment-id='$route.params.id' :work='work' />
</v-col>
</v-row>
</v-container>
</v-container>
</template>
<script>
// ...all the imports
export default {
components: {WorkCard, UIButton},
async asyncData(context) {
// ... fetch and return assignment
},
data() {
return {
works: []
}
},
computed: {
skeletonCards() {
return this.$vuetify.breakpoint.lg ? 4 : 3
}
},
methods: {
async fetchWorks() {
this.works = await this.$nuxt.context.app.apolloProvider.defaultClient.query({
query: worksByAssignmentIdQuery,
variables: {
id: this.$nuxt.context.route.params.id,
}
})
.then(({data}) => data.assignmentWorks)
.catch(err => console.error(err))
},
onIntersect() {
console.log('intersect fired')
this.fetchWorks()
}
},
}
</script>
问题是v -intersect指令即使在视图中还没有出现时也会触发。
我尝试定义阈值。
v-intersect='{
handler: onIntersect,
options: {
threshold: [1.0]
}
}'
但它一直在发射
然后我想也许是因为它是在服务器上渲染的,所以我试着把这部分标记包在了 <client-side>
元素。仍然在发射。我试着把整个页面包在那个元素里,试着把一个空的 <p>
元素之后,并在它上应用该指令--但它仍旧启动了。
我把获取部分放在 fetch()
方法与 fetchOnServer
设为 false
我叫 this.$fetch()
在我 onIntersect
法。而且每次都不停地发射。好像这行总是在视图中,尽管它不是。
我已经没有办法了... 有什么帮助吗?
OK,看来我终于解决了。首先,显然你不能把v-intersect指令放在一个v-row元素上。
所以我创建了一个宽度和高度都为0px的隐形div元素,并在上面应用了v-intersect指令。
...
<div
v-intersect='{
handler: onIntersect,
options: {
threshold: [1.0]
}
}'
class='invisible' />
...
<style scoped>
.invisible {
width: 0;
height: 0;
position: absolute;
bottom: 0;
}
<style>
Thein在我的 onIntersect
方法,我通过 isIntersecting
参数,并调用 fetchWorks
方法,如果它是真的。
onIntersect(entries, observer, isIntersecting) {
if (isIntersecting) {
this.fetchWorks()
}
}
现在,当视图(div)在viewport中时(即使它是不可见的),它就会正确地相交并获取数据,不管是当滚动到那里还是页面被刷新到那个像素上。
由于我需要在项目的其他部分使用v-intersect,我正在考虑将这个div变成一个组件,我将把intersect回调函数传递给它。