如果数据出现在屏幕上(VUE),如何调用方法? [英] How do I call a method if the data appears on the screen (vue)?

查看:114
本文介绍了如果数据出现在屏幕上(VUE),如何调用方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的情况是这样的:

如果我搜索数据,它将显示所有数据医生.但是对于有空的日子,我想单独进行.显示完所有医生的数据后.我想为异步调用可用方法或调用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 store

解决方案

以下是使用 vue-observe-visibility 插件(

 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> 

My case like this :

If I search a data, it will show all data doctor. But for available day, I want to make it separately. when finished displaying all the doctor's data. I want to call the available method for async or call api to display available day. This available day is run when doctor data appears on the screen. So when the doctor's data appears on the screen, it will call available day. If the user scrolls down, it will call available day from another doctor

My code like this :

<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>

Demo and full code like this : https://codepen.io/trendingnews/pen/ZEYpBeW?editors=1010

My problem is If I display all the doctor's data, for example 50 data, it's very fast. only 2-3 seconds

But if I display all the doctor's data and available days, for example 50 data, it's very slow. around 10 seconds

So for available day, I want to make it separate. It's only called when the doctor's data appears on the screen

Doctor data and available day are different API. So this is my problem. I have to handle this from the front end

How can I do that? Is there a package that can help? I have used vuex store in this project

解决方案

Here's a snippet that loads data using the vue-observe-visibility plugin (https://github.com/Akryum/vue-observe-visibility):

  1. The app loads data from a mockup source
  2. A placeholder/preloader shows that something is happening
  3. When the data downloads (after coming into view) the preloader disappears

Pay attention to the parameters of the v-observe-visibility: you have to pass down some ID (custom parameter), you should do it only once (once: true), and you may want some throttling on it.

NOTE: the downloaded data in this snippet is so small, that you may miss the "downloading" state - scroll down fast to the end (there are a 100 posts in the list)

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>

这篇关于如果数据出现在屏幕上(VUE),如何调用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆