VueJS - 向组件 v-for 添加延迟加载
Posted
技术标签:
【中文标题】VueJS - 向组件 v-for 添加延迟加载【英文标题】:VueJS - Add lazy loading to component v-for 【发布时间】:2021-06-04 03:44:19 【问题描述】:我想增加我网站的加载时间。我目前有一个我所有项目的列表,所有项目在第一个页面加载时加载。我想对这些组件实现延迟加载,但我似乎找不到方法。
我有一个名为project-card
的组件:
<project-card v-bind:project="project" v-bind:key="project.id" v-if="projects" v-for="project in filteredProjects"></project-card>
模板文件:
<template>
<div class="project-card rounded dark:bg-gray-800 bg-white overflow-hidden shadow-lg rounded-lg flex flex-col relative">
<img class="w-full h-64 object-cover" :src="'/uploads/' + project.image" >
<div class="px-6 py-4 h-full flex flex-col">
<div class="project-info block min-h-8">
<div class="w-full">
<p class="tracking-widest text-xs title-font font-medium dark:text-white text-gray-500 mb-1"> project.language </p>
</div>
</div>
<div class="project-language flex-1">
<div class="w-5/6 float-left">
<p class="font-bold dark:text-white gilroy text-xl"> project.name </p>
</div>
</div>
<div class="project-description flex-2 space-y-4 py-3 h-full">
<p class="dark:text-white "> project.description | str_limit(128) </p>
</div>
<div class="read-more mt-auto">
<div class="flex items-center flex-wrap ">
<button type="button" @click="openModal" class="font-bold text-sm text-indigo-600 hover:text-indigo-500 transition duration-150 ease-in-out hover:text-indigo-900 read-more-button flex items-center focus:outline-none">
Lees meer <span class="read-more-arrow ml-2">→</span>
</button>
<span class="text-gray-600 mr-3 inline-flex items-center lg:ml-auto md:ml-0 ml-auto leading-none text-sm pr-3 py-1 border-r-2 border-gray-300">
</span>
<span class="text-gray-600 inline-flex items-center leading-none text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke- viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" stroke- d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
project.stargazers_count
</span>
</div>
<project-card-modal :project="project" ref="projectModal"></project-card-modal>
</div>
</div>
</div>
</template>
<script>
import projectCardModalComponent from "./projectCardModalComponent";
export default
components:
projectCardModalComponent
,
methods:
openModal()
this.$refs.projectModal.show = true;
,
props: ['project']
</script>
目前它看起来像这样,所以它给出了它应该如何结果的想法。但我想对这个组件实现延迟加载。我怎样才能做到这一点?
APP.JS
import Vue from "vue";
require('./bootstrap');
window.Vue = require('vue');
Vue.component('project-card', require('./components/projectCardComponent.vue').default);
Vue.component('project-card-modal', require('./components/projectCardModalComponent.vue').default);
Vue.component('contact-form', require('./components/contactFormComponent.vue').default);
Vue.component('contact-form-flash', require('./components/contactFormFlashComponent.vue').default);
Vue.component('project-language-filter-button', require('./components/projectLanguageButtonFilterComponent.vue').default);
Vue.component('project-language-filter-dropdown', require('./components/projectLanguageDropdownFilterComponent.vue').default);
Vue.component('education', require('./components/educationComponent.vue').default);
Vue.component('work-experience', require('./components/workExperienceComponent.vue').default);
Vue.component('sidebar', require('./components/dashboard/dashboardSidebarComponent.vue').default);
Vue.component('projects', require('./components/dashboard/dashboardProjectsComponent.vue').default);
import MugenScroll from 'vue-mugen-scroll'
const app = new Vue(
el: '#app',
data:
showModal: false,
projects: [],
filteredProjects: [],
languages: [],
languageFilterKey: 'all',
workExperiences: [],
educations: [],
search: '',
pageSizeBegin: 0,
pageSizeEnd: null,
projectsLoading: false,
,
mounted: function()
this.getProjects();
this.getWorkExperiences();
this.getAllEducations();
this.getProjectLanguages();
,
created()
this.getFilteredProjects();
,
methods:
getProjects: function()
axios.get('/api/get/projects')
.then(response =>
this.filteredProjects = this.projects = response.data
).catch(err =>
console.log(err)
);
,
getFilteredProjects: function()
for(let i = 0; i < 6; i++)
let count = this.filteredProjects.length + i
,
getProjectLanguages: function()
axios.get('/api/get/project/languages')
.then(response =>
this.languages = response.data
).catch(err =>
console.log(err)
);
,
selectedLanguage: function()
if(this.languageFilterKey !== null)
this.languages.forEach((item) =>
item.active = item.language === this.languageFilterKey;
);
else
this.languageFilterKey = null
,
filterProjectsByLanguage ()
if(this.languageFilterKey === 'all')
this.filteredProjects = this.projects;
else
this.filteredProjects = this.projects.filter((project) =>
return this.languageFilterKey === project.language
);
,
getWorkExperiences: function()
axios.get('/api/get/workexperiences')
.then(response =>
this.workExperiences = response.data
).catch(err =>
console.log(err)
);
,
getAllEducations: function()
axios.get('/api/get/educations')
.then(response =>
this.educations = response.data
).catch(err =>
console.log(err)
);
,
amountOnChange(event)
if(!event.target.value)
this.pageSizeEnd = null;
else
this.pageSizeEnd = event.target.value;
,
computed:
filteredList()
if(!this.pageSizeEnd)
return this.projects.filter((project) =>
return project.name.toLowerCase().includes(this.search.toLowerCase()) || project.language.toLowerCase().includes(this.search.toLowerCase())
)
return this.projects.filter((project) =>
return project.name.toLowerCase().includes(this.search.toLowerCase()) || project.language.toLowerCase().includes(this.search.toLowerCase())
).slice(this.pageSizeBegin, this.pageSizeEnd)
,
)
Vue.filter('str_limit', function (value, size)
if (!value) return '';
value = value.toString();
if (value.length <= size)
return value;
return value.substr(0, size) + '...';
);
【问题讨论】:
【参考方案1】:我认为你想要的实际上是无限滚动。
lot of libs 正在这样做,我最喜欢的是 vue-mugen-scroll。
看看their demo,我认为它接近你的用例。
var vm = new Vue(
el: '#vue-instance',
data:
posts: [],
loading: false
,
created()
this.getPosts()
,
methods:
getPosts()
for (var i = 0; i < 16; i++)
var count = this.posts.length + i
this.posts.push(
title: 'title ' + count
)
);
<script src="https://unpkg.com/vue-mugen-scroll@0.2.5/dist/vue-mugen-scroll.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue-instance" class="container">
<div class="row">
<div class="col-sm-6" v-for="(post, index) in posts">
<div class="card m-4" style="width: 18rem;">
<img class="card-img-top" src="https://via.placeholder.com/350x150">
<div class="card-body">
<h5 class="card-title"><strong> post.title </strong></h5>
</div>
</div>
</div>
</div>
<mugen-scroll :handler="getPosts" :should-handle="!loading">
loading...
</mugen-scroll>
</div>
【讨论】:
我不太明白如何在我的用例中实现这一点。你能示范一下吗?我用 app.js 文件更新了问题 好像你已经有了自己的分页系统,带有 pageSizeBegin 和 pageSizeEnd。 那是一组不同的项目。以上是关于VueJS - 向组件 v-for 添加延迟加载的主要内容,如果未能解决你的问题,请参考以下文章
Vuejs 和 HTML 动态创建复杂的 JSON 对象并使用 V-for 向用户显示相同的对象