Nuxt应用中的Vuetify v-intersect在进入视图之前触发

时间:2020-04-29 12:29:26

标签: vue.js vuetify.js nuxt.js intersection-observer

我的页面的布局如下:

<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。而且它每次都会开火。好像该行始终在视图中,即使不是。

我没办法了...请帮忙吗?

1 个答案:

答案 0 :(得分:0)

好的,看来我终于解决了。首先,显然您不能将v-intersect指令放在v行元素上。

因此,我创建了一个宽度和高度为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>

在我的onIntersect方法中,我要传递isIntersecting参数,并调用fetchWorks方法(如果正确):

onIntersect(entries, observer, isIntersecting) {
  if (isIntersecting) {
    this.fetchWorks()
  }
}

现在,无论是在视图中滚动还是在该像素上刷新页面,它都可以正确相交并在视图(div)处于视口中(即使它不可见)时获取数据。

由于我需要在项目的其他部分中使用v-intersect,因此我正在考虑将该div转换为组件,并将其传递给intersect回调函数。