在构建过程中使用`this`更新函数中的useState会导致未定义错误 - Nuxt 3 & Strapi 4.12 - SFC(script setup)
<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;">
从“~/queries/projects/archive”导入{projectsQuery};
从“~/queries/projects/filter”导入{filterQuery};
const { 数据:filterRes } = 等待 useAsyncQuery(filterQuery)
const { 数据:projectsRes } = 等待 useAsyncQuery(projectsQuery)
var isLoading = useState('isLoading', () => false)
var filterActive = useState('filterActive', () => false)
var filterActiveText = useState('filterActiveText', () => '所有项目')
const itemsUrl = useState('projectsUrl', () => '/projecten/')
const 过滤器 = useState('filters', () => filterRes.value.projectCategories.data)
const 项目 = useState('projects', () =>projectsRes.value.projects.data)
var FilteredProjects = useState('filteredProjects', () => 项目)
函数 switchCategory(id) {
this.isLoading = true
this.filterActive = false;
document.getElementById("projects-container").scrollIntoView({
行为:“平滑”,
});
setTimeout(() => {
如果(id){
this.filters.map((item) => {
if (id == item.id) {
this.filteredProjects = item.attributes.projects.data;
this.filterActiveText = item.attributes.Title;
}
});
} 别的 {
this.filteredProjects = this.projects;
this.filterActiveText = '所有项目';
}
this.isLoading = false;
}, 600)
}</pre>
<p>并且在模板元素中:</p>
<pre class="brush:php;toolbar:false;"><div class="flex flex-col gap-y-8 md:gap-y-24 lg:gap-y-40 过渡所有持续时间-600 缓入出" :class="{
'blur-0': !正在加载,
'模糊':正在加载,
}">
;
<div class="flex flex-col items-start justify- Between">
<div class="sticky top-40 pb-16 lg:pb-20 prose-xl">
{{ project.attributes.Title }}
;
<p class="block">{{ project.attributes.Intro }}</p>
;
<媒体
:url="project.attributes.FeaturedImage.data.attributes.url"
:extension="project.attributes.FeaturedImage.data.attributes.ext"
>>
;</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) => {
isLoading = true
filterActive = false;
document.getElementById("projects-container").scrollIntoView({
behavior: 'smooth',
});
setTimeout(() => {
if (id && filters) {
filters && filters.value.map((item) => {
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>