【问题标题】:How do I call a method if the data appears on the screen (vue)?如果数据出现在屏幕上(vue),我如何调用方法?
【发布时间】:2020-04-07 10:20:49
【问题描述】:

我的情况是这样的:

如果我搜索数据,它将显示所有数据医生。但是对于可用的一天,我想单独制作。当完成显示所有医生的数据时。我想调用可用的异步方法或调用 api 来显示可用日期。当医生数据出现在屏幕上时,这个可用日期就开始了。所以当医生的数据出现在屏幕上时,它会调用可用日。如果用户向下滚动,它将调用另一个医生的可用日

我的代码是这样的:

<v-col
v-for="(item, i) in items"
:key="i"
cols="12"
>
    <v-card
        dark
    >
        <div class="d-flex flex-no-wrap justify-space-between">
        <div>
            <v-card-title
            class="headline"
            v-text="item.doctor"
            ></v-card-title>

            <v-card-subtitle v-text="item.hospital"></v-card-subtitle>
            <v-card-subtitle>Available today</v-card-subtitle>
        </div>

        <v-avatar
            class="ma-3"
            size="125"
            tile
        >
            <v-img :src="item.src"></v-img>
        </v-avatar>
        </div>
    </v-card>
</v-col>

演示和完整代码如下:https://codepen.io/trendingnews/pen/ZEYpBeW?editors=1010

我的问题是 如果我显示所有医生的数据,例如 50 条数据,它非常快。只需 2-3 秒

但如果我显示所有医生的数据和可用天数,例如 50 个数据,它会很慢。大约 10 秒

所以对于可用的一天,我想把它分开。只有当医生的数据出现在屏幕上时才会调用它

医生数据和可用日期是不同的 API。所以这是我的问题。我必须从前端处理这个

我该怎么做?有可以提供帮助的软件包吗?我在这个项目中使用了 vuex 商店

【问题讨论】:

  • 听起来您正在寻找一个 Intersection Observer 库来在屏幕上滚动到医生时执行操作?如果是这种情况,我会查看 vue-observe-visibilityvue-intersect 之类的内容。
  • @StevenB。这真的适合我的情况吗?我的情况是这样的。第一次加载时,它将显示所有医生的数据。但是对于每个医生的可用日期,当用户向下滚动时,当医生出现在屏幕上时会调用它

标签: vue.js asynchronous vue-component loading vuetify.js


【解决方案1】:

这是一个使用 vue-observe-visibility 插件 (https://github.com/Akryum/vue-observe-visibility) 加载数据的 sn-p:

  1. 应用从模型源加载数据
  2. 占位符/预加载器显示正在发生的事情
  3. 数据下载后(进入视图后),预加载器消失

注意v-observe-visibility的参数:你必须传递一些ID(自定义参数),你应该只做一次(once: true),你可以想要对其进行一些节流。

注意:此 sn-p 中下载的数据非常小,您可能会错过“正在下载”状态 - 快速向下滚动到最后(列表中有 100 个帖子)

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: {
    posts: []
  },
  methods: {
    fetchPosts(id) {
      return fetch(`https://jsonplaceholder.typicode.com/posts/${id ? id : ''}`)
        .then(response => response.json())
        .then(json => json)
    },
    async visibilityChanged(isVisible, entry, id) {
      const post = await this.fetchPosts(id)
      Vue.set(this.posts.find(e => e.id === id), 'body', post.body)
    }
  },
  async mounted() {
    const data = await this.fetchPosts()
    // this is only for the mockup data: I pluck the id and title,
    // so the body can be downloaded later
    this.posts = data.map(e => ({
      id: e.id,
      title: e.title
    }))
  }
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<script src="https://unpkg.com/vue-observe-visibility/dist/vue-observe-visibility.min.js"></script>

<div id="app">
  <v-app>
    <v-container>
      <v-row v-for="post in posts" :key="post.id" v-observe-visibility="{
          callback: (isVisible, entry) => visibilityChanged(isVisible, entry, post.id),
          once: true,
          throttle: 100
        }">
        <v-col>
          <v-row>
            <v-col>
              <b>{{post.title}}</b>
            </v-col>
          </v-row>
          <v-row>
            <v-col>
              <v-progress-circular indeterminate color="primary" v-if="!post.body"></v-progress-circular>
              {{post.body}}
            </v-col>
          </v-row>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</div>

【讨论】:

  • 真的适合我的情况吗?我已经在我的案例中实现了它。但似乎发生了很多异步。当我在输入文本中输入内容时,它将是异步的。当我向下滚动时,它也将是异步的
  • @SuccessMan 从外部 API 下载数据将始终是异步的。如果响应到达缓慢(比您需要/想要的慢),您必须调查其缓慢的原因。
  • 是的。但它看起来像重复异步。如果 id 已经异步,则不再需要异步。除此之外,当我输入输入文本时,它会自动异步。不应该
  • @SuccessMan once: true 确保它在可见时只下载一次。否则,您可以检查内容是否已在 visibilityChanged 和/或 fetchPosts 中下载。
  • 好的,我会尝试详细研究这个包。顺便说一句,这个包是解决我的问题的唯一方法吗?还是有其他方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多