【问题标题】:VueJS - Add lazy loading to component v-forVueJS - 向组件 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" alt="">
        <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-width="2" 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-width="2" 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) + '...';
});

【问题讨论】:

    标签: laravel vue.js vuejs2 vue-component


    【解决方案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。
    • 那是一组不同的项目。
    猜你喜欢
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    相关资源
    最近更新 更多