首页前端开发JavaScriptVue 虚拟列表的实战示例

Vue 虚拟列表的实战示例

时间2024-02-01 04:20:02发布访客分类JavaScript浏览882
导读:收集整理的这篇文章主要介绍了Vue 虚拟列表的实战示例,觉得挺不错的,现在分享给大家,也给大家做个参考。 目录序言设计实现小结序言现如今,我们总是在无止境的刷。刷微博、刷抖音、刷沸点.....
收集整理的这篇文章主要介绍了Vue 虚拟列表的实战示例,觉得挺不错的,现在分享给大家,也给大家做个参考。
目录
  • 序言
  • 设计
  • 实现
  • 小结

序言

现如今,我们总是在无止境的刷。刷微博、刷抖音、刷沸点......一次次丝滑下拉体验的背后却是前端攻城狮的用心。

本篇讨论基于 Vue.js 的列表无限下拉实践。

我们的目标就是:让列表下拉纵享丝滑,而不是像以往的下拉就 loading 等待的体验。

  • 译自 Better Programming
  • 在线 Demo

设计

咱还是用 vue cli 来快速构建项目。

这是主页面:

// EndlessList.vue

template>
     div class="endless-scrolling-list">
      !-- 搜索框 -->
      div class="seArch-box">
       input tyPE="text" v-model="searchQuery"/>
      /div>
      p class="center" v-if="results.length == 0 &
    &
     !loading">
       Start typing to search something.  /p>
      !-- 虚拟列表 -->
      virtual-list   :data-key="'pageid'"   :data-sources="results"   :data-component="ITemComponent"   :page-mode="true"   />
      !-- loading -->
      loader v-if="loading" />
     /div>
    /template>
    

其中核心当然是virtual-list组件啦~

这里的虚拟列表,我们用到一个三方库 Vue Virtual Scroll List,它在 Github 上又 2.5k+ 的 stars。类比于 react 的 react-virtualized 库。

大量的 DOM 元素会使得我们的网页非常“重”。当 DOM 元素超过 1500 至 2000 个的时候,页面就开始又延迟,尤其是在小型的、性能差的设备上尤为明显。

想象一下,有一个无线滚动的页面,你不断的下拉,它实际上可能形成了上万个 DOM 元素,每个元素还包含子节点,这样将消耗巨大的性能。

Virtual scrollers 正是来解决这个问题的。

如上图,已经表示的很清楚了。列表分为可见区域和缓冲区域,超出这个范围的列表 DOM 都将被删除。

好啦,准备工作已就绪,Let`s get it!

实现

// imports.js(EndlessList.vue)

import axios From 'axios';
    import lodash from 'lodash';
    import VirtualList from 'vue-virtual-scroll-list';
    import Searchresult from './SearchResult';
    import Loader from './Loader';
export default {
 name: 'EndlessList', components: {
  VirtualList,  Loader }
, data() {
  return {
   searchQuery: '',   currentPage: 0,   results: [],   itemComponent: SearchResult,   loading: false  }
 }
,}
    ;
    

我们引入第三方库 axios 和 loadsh,以便后续使用。

其中,itemComponent 是 virtual-list 的属性,为此我们需要新建一个 SearchResult 子组件,作为搜索结果单元。

代码如下:

// SearchResult.vue

template>
     div class="list-item">
      h3>
   {
{
 source.title }
}
      /h3>
      div v-htML="source.snippet">
    /div>
     /div>
    /template>
    script>
export default {
 PRops: {
  index: {
   // index of current item   type: Number,  }
,  source: {
   type: Object,   default() {
    return {
}
    ;
   }
,  }
, }
,}
    ;
    /script>
    style scoped>
.list-item {
     padding: 0 10px 20px 10px;
}
.list-item h3 {
     margin: 0;
     padding-bottom: 10px;
}
    /style>
    

我们可以通过搜索标题或描述来得到结果,请求数据来源于维基百科。

search(query, page) {
 // We prepare the data that the Wikipedia API expects. const data = {
  action: "query",  format: "json",  list: "search",  continue: "-||",  utf8: 1,  srsearch: query,  sroffset: page * 10,  origin: "*", }
    ;
     // And then we convert these params TO GET params in the format // action=query&
format=JSON ... const params = Object.keys(data)  .map(function(k) {
       return data[k] == ""    ? ""    : encodeURIComponent(k) + "=" + encodeURIComponent(data[k]);
  }
    )  .join("&
    ");
 // We prepare the url with the params string const searchUrl = `https://en.wikipedia.org/w/api.php?${
params}
    `;
     // we set loading to true so that we can display the loader  this.loading = true;
     // Then we execute the request and concatenate the results axios.get(searchUrl).then((response) =>
 {
      this.results = this.results.concat(response.data.query.search);
      // And of course set loading to false to hide the loader.  this.loading = false;
 }
    );
}
    

搜索的方法已经写好,接着就是调用。

  1. 当用户键入内容的搜索时候会调用。
  2. 当下拉的时候会调用。

// EndlessList.vue

script>
export default {
 // data() and methods skipped for brevity watch: {
  searchQuery: {
   immediate: true,   handler: lodash.debounce(function (newVal) {
    if (newVal == "") {
         return;
    }
        this.results = [];
        this.currentPage = 0;
        this.search(newVal, this.currentPage);
        this.search(newVal, this.currentPage + 1);
        this.currentPage = 2;
   }
, 200),  }
, }
, mounted() {
      const vm = this;
  window.onscroll = lodash.debounce(function () {
       VAR distanceFromBottom =    document.body.scrollHeight - window.innerHeight - window.scrollY;
       if (distanceFromBottom  400 &
    &
 vm.searchQuery !== "") {
        vm.search(vm.searchQuery, vm.currentPage);
        vm.currentPage++;
   }
  }
, 100, {
leading: true}
    );
 }
,}
    /script>
    

显而易见,当 searchQuery 变化的时候,我们会得到新的搜索结果。当然,这里的输入框也用到了防抖函数。

另一个需要注意的是,我们第一次搜索加载了两页的结果,用户就会有一定的滚动空间,这样就可以保持顺畅的感觉。

我们在滚动的事件中也加了防抖函数。这里设一个疑问:为什么要在 window.onscroll 事件下设置 leading 为 true ?

然后我们运行程序看效果:

npm run dev

如何?只要你不是疯狂下拉,基本上感受不到 loading 的过程~

小结

用户不会希望每下拉十条结果就要等待新的十条结果加载出来!所以我们需要有缓冲区,还未下拉到底的时候就预判它到底然后提前加载。这便是丝滑体验的内核。

当然不在视图区和缓冲区的 DOM 都将被删除,这也是页面不形成大量 DOM 元素的精髓。

这样动态的处理列表的确是编程人员的一种智慧和用心。

你可以把 项目 克隆到本地再体会一下。以上便是本次分享~

以上就是Vue 虚拟列表的实现示例的详细内容,更多关于Vue 虚拟列表的资料请关注其它相关文章!

您可能感兴趣的文章:
  • vue实现虚拟列表功能的代码
  • 使用 Vue 实现一个虚拟列表的方法
  • Vue多选列表组件深入详解
  • vue从后台渲染文章列表以及根据id跳转文章详情详解
  • Vue 列表页带参数进详情页的操作(router-link)
  • vue 公共列表选择组件,引用Vant-UI的样式方式
  • vue实现列表拖拽排序的功能
  • vue实现前端列表多条件筛选
  • vue实现点击按钮“查看详情”弹窗展示详情列表操作
  • vue-列表下详情的展开与折叠案例
  • vue实现循环滚动列表

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

vue

若转载请注明出处: Vue 虚拟列表的实战示例
本文地址: https://pptw.com/jishu/594912.html
用户标识符合法的条件是什么 正则一则 将金额转换成人民币大写的代码

游客 回复需填写必要信息