在构建过程中使用`this`更新函数中的useState会导致未定义错误 - Nuxt 3 & Strapi 4.12 - SFC(script setup)
P粉436410586
P粉436410586 2023-08-03 16:40:32
[Vue.js讨论组]



"@strapi/strapi": "4.12.0",

"nuxt": "^3.6.5",

在我的开发环境中,我有一个项目页面,带有一个分类筛选器,可以显示所有项目或带有相应项目的分类。

我正在使用useAsyncQuery从Strapi获取项目和分类。

在筛选器中,有一个下拉菜单,其中包含各种分类。点击这些分类时,将调用函数switchCategory(filter.id)。在该函数中,使用this更新了各种状态。

请查看以下脚本设置:

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', () => false)
var filterActive = useState('filterActive', () => false)

var filterActiveText = useState('filterActiveText', () => 'Alle projecten')
const projectsUrl = useState('projectsUrl', () => '/projecten/')

const filters = useState('filters', () => filterRes.value.projectCategories.data)
const projects = useState('projects', () => projectsRes.value.projects.data)
var filteredProjects = useState('filteredProjects', () => projects)

function switchCategory(id) {

  this.isLoading = true
  this.filterActive = false;

  document.getElementById("projects-container").scrollIntoView({
    behavior: 'smooth',
  });


  setTimeout(() => {
    if (id) {
      this.filters.map((item) => {
        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)
}

并且在模板元素中:

<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,
}">
  <div class="grid md:grid-cols-2 gap-8 md:gap-16 lg:gap-24 relative" v-for="(project, id) in filteredProjects" :key="id">
    <Nuxt-Link class="absolute inset-0 w-full h-full z-10"
      :to="projectsUrl + project.attributes.Slug"></Nuxt-Link>
    <div class="flex flex-col items-start justify-between">
      <div class="sticky top-40 pb-16 lg:pb-20 prose-xl">
        <h3 class="text-xl md:text-4xl lg:text-5xl font-bold">{{ project.attributes.Title }}</h3>
        <p class="block">{{ project.attributes.Intro }}</p>
      </div>
      <Button class="flex mb-4" color="light" :to="projectsUrl + project.attributes.Slug">
        Project bekijken
      </Button>
    </div>
    <div class="-order-1 md:order-1 relative">
      <div class="aspect-video md:aspect-square lg:aspect-[12/18] relative">
        <Media
          :url="project.attributes.FeaturedImage.data.attributes.url"
          :extension="project.attributes.FeaturedImage.data.attributes.ext"
        />
      </div>
    </div>
  </div>

</div>

当我构建项目时,使用nuxt build,然后使用node .output/server/index.mjs启动一个Node服务器,项目能够正常加载。但是当我尝试进行筛选时,试图在switchCategory函数内更新isLoading和filterActive等变量时,它抛出了错误:TypeError: Cannot set properties of undefined (setting 'isLoading')。

修复尝试 #1

我想,也许在构建后,它无法理解this上下文(因为当我尝试console.log时,this也是undefined)。所以我尝试重构代码,像这样:

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)
}

我将普通函数更改为箭头函数并删除了this。

在setTimeout中,我不得不将filters.map更改为filters.value.map(不太确定为什么格式发生了变化)。

现在代码运行正常(没有错误),但它没有更新模板中项目循环的DOM。

修复尝试 #2

在搜索和调试了相当长时间后,我在Vue文档中找到了defineExpose的内容。

它提到脚本设置默认是"closed"的。我(绝望地)将其添加到了我的脚本设置中,包括所有变量:

defineExpose({
  filterRes,
  projectsRes,
  pageRes,
  isLoading,
  filterActive,
  filterActiveText,
  projectsUrl,
  filters,
  projects,
  filteredProjects,
})

不幸的是,正如预料的那样,它并没有神奇地起作用。

解决方案?
我很可能是以错误的方式来看待这个问题,但我无法想出其他解决办法。

我是否漏掉了什么?


P粉436410586
P粉436410586

全部回复(1)
P粉627427202

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

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


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

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