Vuetify v-intersect в приложении Nuxt срабатывает до входа в вид - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть страница со следующим макетом:

<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 голосов
/ 29 апреля 2020

ОК, похоже, я наконец-то решил это. Во-первых, очевидно, вы не можете поместить директиву v-intersect в элемент v-row.

Итак, я создал невидимый элемент div с шириной и высотой 0px, к которому я применил директиву 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.

...