Nuxt.js项目中如何让Isotope等待API数据加载完成后再初始化
解决方案
问题根因就是你推测的:getProjects 是异步请求,页面重载时请求未返回,mounted 钩子执行时 projects 还没有数据,导致 Isotope 初始化失败。你可以通过监听 projects 数据状态,等数据加载完成后再初始化 Isotope 来解决,同时修复原有代码的变量作用域问题,修改方案如下:
核心修改点
- 新增
data属性存储 Isotope 实例,避免重复初始化,同时让filterItems方法可以正常访问实例 - 移除
mounted钩子中的 Isotope 调用,新增watch监听projects变化,数据加载完成后再执行初始化逻辑 - 用
$nextTick保证 DOM 渲染完成后再执行布局操作,适配 Nuxt SSR 特性 - 修复
filterItems方法中无法访问 Isotope 实例的 Bug
修改后完整代码
<script> /* eslint-disable */ let Isotope; let imagesLoaded; if (process.client) { Isotope = require('isotope-layout'); imagesLoaded = require('imagesloaded') } export default { data() { return { iso: null // 全局存储Isotope实例 } }, mounted() { // 移除原有的isotope、isCaseStudy调用,改到watch中触发 }, computed: { page(){ //return this.$store.getters.filterProject; return this.pages.find(page => page.id === 110) }, pages(){ return this.$store.state.pages; }, projects(){ return this.$store.state.projects; }, }, watch: { projects: { handler(newProjects) { // 仅在客户端、有项目数据、未初始化过Isotope的情况下执行 if (process.client && newProjects.length > 0 && !this.iso) { // 等待项目列表DOM渲染完成后再操作 this.$nextTick(() => { this.isCaseStudy(); this.isotope(); }) } }, immediate: true // 页面初次加载时如果已有数据直接触发初始化 } }, created(){ this.$store.dispatch("getPages"); this.$store.dispatch("getProjects"); }, methods: { isCaseStudy(){ $(".item").each(function(){ $(this).has('img.case-studyImg').addClass('case-study'); }); }, isotope() { console.log("isotope wird ausgeführt"); if(this.projects.length != 0){ console.log("projekte geladen!") // 把实例存到data中,方便全局调用 this.iso = new Isotope('.items', { itemSelector: '.item', masonry: { columnWidth: '.grid-sizer' } }); imagesLoaded(".items").on( 'progress', () => { console.log("each image loaded"); this.iso.layout(); }); }else{ console.log("keine projekte"); } }, filterItems(selector) { // 增加实例存在判断,避免报错 if (!this.iso) return let oldActive = $(".filters .btn-primary").first(); console.log(oldActive); if(oldActive.hasClass(selector)){ return; } let currentActive = $(".filters a." + selector).first(); console.log(currentActive); currentActive.removeClass("btn-default").addClass("btn-primary"); oldActive.removeClass("btn-primary").addClass("btn-default"); this.iso.arrange({filter: `.${selector}`}); } } } </script>
内容的提问来源于stack exchange,提问作者nip
相关产品推荐
相关产品推荐

