SoFunction
Updated on 2025-04-12

The use of list in vant and the first load triggering to solve the problem twice

Use list in vant and trigger two times for the first load

The following is the basic usage method of list. The main principle is that when the page data is less than the height of offset, the load will be triggered. The interface needs to be called in the load to send the data of the next page. Therefore, after sending, you need to add one of the properties of the set page and push the obtained new value into the array of receiving data, rather than directly assigning values. If the value is assigned directly, there will be only new values ​​in the array, and the previous value will be overwritten.

After the call is completed, the loading style is closed and it is determined whether there is still data in the database. If not, finish it to true, indicating that it has been loaded.

The first load triggers twice to resolve the problem

1. Called on mounted or create, because it is possible that the load monitors the data below the height when the data has not returned, and it has also been sent once. By the time the data comes back, it has requested twice. So there is no need to call it, just leave it to load for detection.

Too high, the default height is 300. Once you get data, only 5 pieces of data are obtained at a time. Although the page height is covered, it will be sent twice after a slight touch.

3. If the requested data is too small, the requested data is not enough to cover the page and it will be loaded twice. You can see the first example of the document list.

<template>
  <div>
    <div class="groupBuyingList">
      <!-- Add to load -->
      <van-list
        v-model="loading"
        :finished="finished"
        finished-text="No more"
        @load="onLoad"
        :offset='50'
      >
        <!-- Each module -->
        <div class="activity" v-for="(item, index) in results" :key="index">
          <img :src="" alt="" />
          <div class="title">{{  }}</div>
          <div class="groupPeople">
            <span>{{  }}</span>
          </div>
          <div class="operation">
            <div class="money">
              <!-- Group price -->
              <div class="groupMoney">
                <span>¥</span>{{  }} <span>rise</span>
              </div>
              <!-- Original price -->
              <div class="originalCost">¥{{  }}</div>
            </div>
            <div class="share" @click="handleGo(item)">
              <span> Go to start a group </span>
            </div>
          </div>
        </div>
      </van-list>
    </div>
  </div>
</template>
<script>
import { activityList } from "../../../api/appletGroupBuying/groupBuyingActivity";
export default {
  data() {
    return {
      userInfo: {
        // Number of items        pageNum: 1,
      },
      loading: false, //Loading status      finished: false, // Whether to load      // Receive list data      results: [],
      // Total number of      rowCount: "",
    };
  },
  mounted() {
  },
  methods: {
    async activityList() {
      let res = await activityList();//Send a request      // ();
      // If there is no data      if ( === null) {
         = [];
         = true; // Stop loading      } else {
        // Total number of         = ;
        // Put data into an array        (...);
         = false; // Loading status ends        // If the list length is greater than or equal to the total number of data, all data will be loaded.        // = true End loading status         >=  ? ( = true) : "";
      }
    },
    onLoad() {
      (); // Call the above method to request data      ++; // Add one page number    },
  },
};
</script>
<style lang="less" scoped>
.groupBuyingList {
  padding: 20px;
  background: #f4f4f4;
  //Each activity  .activity {
    padding: 30px 35px;
    margin-bottom: 32px;
    width: 710px;
    background: #ffffff;
    border-radius: 20px;
    box-sizing: border-box;
    > img {
      width: 100%;
    }
    // Title    .title {
      margin-top: 30px;
      width: 100%;
      height: 40px;
      font-size: 28px;
      font-weight: bold;
      line-height: 40px;
      color: #545353;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    // Number of people buying a group    .groupPeople {
      margin-top: 26px;
      margin-bottom: 14px;
      display: flex;
      align-items: center;
      span {
        padding: 0 3px 0 3px;
        border: 2px solid #ff7f00;
        border-radius: 10px;
        font-size: 24px;
        font-weight: 400;
        line-height: 33px;
        color: #ff7f00;
      }
    }
    .operation {
      display: flex;
      justify-content: space-between;
      .money {
        display: flex;
        // Group price        .groupMoney {
          display: flex;
          margin-right: 13px;
          height: 62px;
          font-size: 44px;
          font-weight: bold;
          line-height: 62px;
          color: #ff8105;
          span {
            font-size: 30px;
          }
        }
        // Original price        .originalCost {
          text-decoration: line-through;
          width: 119px;
          height: 40px;
          font-size: 28px;
          line-height: 60px;
          color: #b5b4b1;
        }
      } //Share to get customers      .share {
        width: 180px;
        height: 60px;
        background: #ff8105;
        display: flex;
        align-items: center;
        border-radius: 20px;
        span {
          width: 100%;
          line-height: 60px;
          text-align: center;
          font-size: 29px;
          font-weight: bold;
          line-height: 37px;
          color: #ffffff;
        }
      }
    }
  }
}
</style>

Use list list component in vant

List running mechanism:

List will listen to the browser's scrolling events and calculate the position of the list. When the distance between the bottom of the list and the visible area is less than offset, List will trigger a load event.

1. Infrastructure

<van-list 
    v-model="loading"                     // Whether to display loading status    :finished="finished"                 // Is it loaded?    finished-text="No more"            // Loading prompt document    @load="onLoad"                         // Event triggers when the scroll bar is offset from the bottom    offset="300"                        // @load is triggered when the scroll bar is offset from the bottom (default 300)    :="error"                 // Whether to display load failure status    error-text="Request failed, click Reload"    // Loading failure prompt document    >
    
   <van-cell v-for='(item, index) in list' :key="index">  // Loop list data           <div>{{item}}Looped data<div>
   </van-cell>
 </van-list>  
statement:
data() {
    return {
      loading: false,         // Is it in the loading state      finished: false,        // Whether it has been loaded      error: false,           // Whether the loading failed      list: [],               // Data item      page: 1,                // Pagination      page_size: 10           // Number of bars per page      total: 0                // Total number of data    }
}

Definition method

methods: {
    onLoad() {
      // Asynchronously update data      // setTimeout is only for examples, and in real scenarios, it is usually ajax request.      setTimeout(() => {
        for (let i = 0; i < 10; i++) {
          ( + 1);
        }
 
        // Loading status ends         = false;
 
        // All data is loaded        if ( >= 40) {
           = true;
        }
      }, 1000);
    },
  },
};

4. Call API to render the page

Import this interface import {  } from '@/api/'

async onLoad () {
  const res = await Interface method name(, ())
  // The obtained data  const arr =  // It is an array  // 1. Append data to list  //   Expand the array  (...arr)
  // 2. Set loading to false   = false
  // 3. Determine whether all data is loaded. If yes: finished set to true  if ( === 0) {
    // It means that the data cannot be retrieved     = true
  }
  // 4. Tip users on the page  this.$('Successfully loaded data')
}

What do loading and finished mean?

List has the following three states, and understanding these states will help you use the List component correctly:

  • Unloading, loading is false. At this time, whether the load event will be triggered based on the scroll position of the list (if the list content is less than one screen, it will be sent directly)
  • Loading is true, indicating that an asynchronous request is being sent, and the load event will not be triggered at this time.
  • Loading is completed, finished is true, and the load event will not be triggered at this time.

After each request is completed, you need to manually set loading to false to indicate the loading is over

The above is personal experience. I hope you can give you a reference and I hope you can support me more.