PrefaceNowadays, we are always swiping endlessly. Check Weibo, check Tik Tok, check Boiling Point... Behind each smooth scrolling experience is the dedication of the front-end engineers. This article discusses the practice of infinite drop-down lists based on Vue.js. Our goal is to make the pull-down process of the list smooth, instead of the previous experience of waiting for the list to load.
designLet's use Vue CLI to quickly build the project. This is the main page: // EndlessList.vue <template> <div class="endless-scrolling-list"> <!-- Search Box --> <div class="search-box"> <input type="text" v-model="searchQuery"/> </div> <p class="center" v-if="results.length == 0 && !loading"> Start typing to search for something. </p> <!-- Virtual list --> <virtual-list :data-key="'pageid'" :data-sources="results" :data-component="itemComponent" :page-mode="true" /> <!-- loading --> <loader v-if="loading" /> </div> </template> The core of course is the virtual-list component~ For the virtual list here, we use a third-party library Vue Virtual Scroll List, which has 2.5k+ stars on Github. Analogous to react's react-virtualized library. A large number of DOM elements will make our web pages very "heavy". When the DOM exceeds 1500-2000 elements, the page starts to lag, especially on small, slow devices. Imagine that there is an infinitely scrolling page. If you keep pulling down, it may actually form tens of thousands of DOM elements, each of which contains child nodes, which will consume huge performance. Virtual scrollers are here to solve this problem. As shown in the picture above, it has been clearly stated. The list is divided into a visible area and a buffer area. Any list DOM outside this range will be deleted. Okay, the preparations are ready, let's get it! accomplish// 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 } }, }; We introduce third-party libraries axios and loadsh for subsequent use. Among them, itemComponent is a property of virtual-list, so we need to create a new SearchResult subcomponent as the search result unit. The code is as follows: // 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> We can get results by searching for titles or descriptions, and the request data comes from Wikipedia. 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; }); } The search method has been written, and the next step is to call it.
// 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> Obviously, when the searchQuery changes, we will get new search results. Of course, the input box here also uses the anti-shake function. Another thing to note is that our first search loaded two pages of results so the user would have some room to scroll, which would keep the feeling smooth. We also added an anti-shake function to the scrolling event. Here is a question: Why should we set leading to true in the window.onscroll event? Then we run the program to see the effect: npm run dev how? As long as you don't scroll down crazily, you basically can't feel the loading process~ summaryUsers don’t want to wait for ten new results to load every time they scroll down ten results! So we need a buffer to predict the bottom before it is pulled down and load it in advance. This is the core of the silky experience. Of course, all DOM elements that are not in the view area and buffer will be deleted. This is also the essence of not forming a large number of DOM elements on the page. Such dynamic processing list is indeed a kind of wisdom and care of programmers. You can clone the project locally and try it out. The above is this sharing~ The above is the details of the implementation example of Vue virtual list. For more information about Vue virtual list, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: A brief discussion on MySQL event planning tasks
>>: Complete steps to configure IP address in Ubuntu 18.04 LTS
Vue bus mechanism (bus) In addition to using vuex...
This article introduces common problems of Xshell...
premise In complex scenarios, a lot of data needs...
Table of contents Preface Implementation ideas Ef...
This article shares the specific code of Vue to s...
Preface: I have always wanted to know how a SQL s...
Table of contents Preface 🍹Preparation 🍲vue3 usag...
Table of contents WXS Response Event Plan A Page ...
Preface At first, I wanted to use wget to downloa...
The <base> tag specifies the default addres...
【Foreword】 The SMS function of our project is to ...
1. Basic Use It can be instantiated through the M...
I’ve always preferred grayscale images because I t...
Table of contents 1. Introduction to the Implemen...
This article shares the MySQL backup script for y...