Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

vue.js - How do I call a method if the data appears on the screen (vue)?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...