在Nuxt应用中Vuetify v-intersect在进入视图之前就会发生火灾。

问题描述 投票:0回答:1

我有一个布局如下的页面。

<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 法。而且每次都不停地发射。好像这行总是在视图中,尽管它不是。

我已经没有办法了... 有什么帮助吗?

vue.js vuetify.js nuxt.js intersection-observer
1个回答
0
投票

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回调函数传递给它。

© www.soinside.com 2019 - 2024. All rights reserved.