在构建过程中使用`this`更新函数中的useState会导致未定义错误 - Nuxt 3 & Strapi 4.12 - SFC(script setup)
P粉436410586
P粉436410586 2023-08-03 16:40:32
[Vue.js讨论组]
<p><br /></p><h2><br /></h2> <p><code>"@strapi/strapi": "4.12.0",</code></p> <p><code>"nuxt": "^3.6.5",</code></p> <p>在我的开发环境中,我有一个项目页面,带有一个分类筛选器,可以显示所有项目或带有相应项目的分类。<br /><br />我正在使用useAsyncQuery从Strapi获取项目和分类。<br /><br />在筛选器中,有一个下拉菜单,其中包含各种分类。点击这些分类时,将调用函数switchCategory(filter.id)。在该函数中,使用this更新了各种状态。<br /><br />请查看以下脚本设置:</p><p><code></code></p> <pre class="brush:php;toolbar:false;"> import { projectsQuery } from "~/queries/projects/archive"; import { filterQuery } from "~/queries/projects/filter"; const { data: filterRes } = await useAsyncQuery(filterQuery) const { data: projectsRes } = await useAsyncQuery(projectsQuery) var isLoading = useState('isLoading', () =&gt; false) var filterActive = useState('filterActive', () =&gt; false) var filterActiveText = useState('filterActiveText', () =&gt; 'Alle projecten') const projectsUrl = useState('projectsUrl', () =&gt; '/projecten/') const filters = useState('filters', () =&gt; filterRes.value.projectCategories.data) const projects = useState('projects', () =&gt; projectsRes.value.projects.data) var filteredProjects = useState('filteredProjects', () =&gt; projects) function switchCategory(id) { this.isLoading = true this.filterActive = false; document.getElementById("projects-container").scrollIntoView({ behavior: 'smooth', }); setTimeout(() =&gt; { if (id) { this.filters.map((item) =&gt; { if (id == item.id) { this.filteredProjects = item.attributes.projects.data; this.filterActiveText = item.attributes.Title; } }); } else { this.filteredProjects = this.projects; this.filterActiveText = 'Alle projecten'; } this.isLoading = false; }, 600) }</pre> <p>并且在模板元素中:</p> <pre class="brush:php;toolbar:false;">&lt;div class="flex flex-col gap-y-8 md:gap-y-24 lg:gap-y-40 transition-all duration-600 ease-in-out" :class="{ 'blur-0': !isLoading, 'blur': isLoading, }"&gt; &lt;div class="grid md:grid-cols-2 gap-8 md:gap-16 lg:gap-24 relative" v-for="(project, id) in filteredProjects" :key="id"&gt; &lt;Nuxt-Link class="absolute inset-0 w-full h-full z-10" :to="projectsUrl + project.attributes.Slug"&gt;&lt;/Nuxt-Link&gt; &lt;div class="flex flex-col items-start justify-between"&gt; &lt;div class="sticky top-40 pb-16 lg:pb-20 prose-xl"&gt; &lt;h3 class="text-xl md:text-4xl lg:text-5xl font-bold"&gt;{{ project.attributes.Title }}&lt;/h3&gt; &lt;p class="block"&gt;{{ project.attributes.Intro }}&lt;/p&gt; &lt;/div&gt; &lt;Button class="flex mb-4" color="light" :to="projectsUrl + project.attributes.Slug"&gt; Project bekijken &lt;/Button&gt; &lt;/div&gt; &lt;div class="-order-1 md:order-1 relative"&gt; &lt;div class="aspect-video md:aspect-square lg:aspect-[12/18] relative"&gt; &lt;Media :url="project.attributes.FeaturedImage.data.attributes.url" :extension="project.attributes.FeaturedImage.data.attributes.ext" /&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;</pre> <p>当我构建项目时,使用nuxt build,然后使用node .output/server/index.mjs启动一个Node服务器,项目能够正常加载。但是当我尝试进行筛选时,试图在switchCategory函数内更新isLoading和filterActive等变量时,它抛出了错误:TypeError: Cannot set properties of undefined (setting 'isLoading')。<br /><br />修复尝试 #1<br /><br />我想,也许在构建后,它无法理解this上下文(因为当我尝试console.log时,this也是undefined)。所以我尝试重构代码,像这样:</p><p><code></code><code></code><code></code></p> <pre class="brush:php;toolbar:false;">const switchCategory = (id) =&gt; { isLoading = true filterActive = false; document.getElementById("projects-container").scrollIntoView({ behavior: 'smooth', }); setTimeout(() =&gt; { if (id &amp;&amp; filters) { filters &amp;&amp; filters.value.map((item) =&gt; { if (id == item.id) { filteredProjects = item.attributes.projects.data; filterActiveText = item.attributes.Title; } }); } else { filteredProjects = projects; filterActiveText = 'Alle projecten'; } isLoading = false; }, 600) }</pre> <p>我将普通函数更改为箭头函数并删除了this。<br /><br />在setTimeout中,我不得不将filters.map更改为filters.value.map(不太确定为什么格式发生了变化)。<br /><br />现在代码运行正常(没有错误),但它没有更新模板中项目循环的DOM。<br /><br />修复尝试 #2<br /><br />在搜索和调试了相当长时间后,我在Vue文档中找到了defineExpose的内容。<br /><br />它提到脚本设置默认是"closed"的。我(绝望地)将其添加到了我的脚本设置中,包括所有变量:</p><p><code></code><em></em></p> <pre class="brush:php;toolbar:false;">defineExpose({ filterRes, projectsRes, pageRes, isLoading, filterActive, filterActiveText, projectsUrl, filters, projects, filteredProjects, })</pre> <p>不幸的是,正如预料的那样,它并没有神奇地起作用。<br /><br />解决方案?<br />我很可能是以错误的方式来看待这个问题,但我无法想出其他解决办法。<br /><br />我是否漏掉了什么?</p><p><br /></p>
P粉436410586
P粉436410586

全部回复(1)
P粉627427202

我不确定能否提供一个完整的可工作的代码片段,但也许我可以指导您找到解决方案。

useState只在构建时或组件渲染时可用。因此,在渲染后更改查询参数不会使其更新。也许在状态变更后重新渲染组件会有帮助?


热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号