Pinia 商店发送多个 API 请求

问题描述 投票:0回答:1

我有 GridLayout,它有一个 GridItem(从 vue3-grid-layout 导入)。它们是可拖动且可调整大小的。当我移动项目或调整项目大小时(在完成时,而不是在更改期间),此组件(名为 Widget)会向父级(名为 Candidates 页面)发送所有项目的位置和大小的新值。父组件(候选人页面)有“保存”按钮,单击该按钮会调用保存函数,然后调用存储中的函数以将 POST 请求发送到 API 并更新位置和大小。这就是它应该如何工作的,这部分是有效的。

但是,当我第一次点击“保存”按钮,然后再次选择编辑网格时(这里不过多讨论逻辑,但是有一个名为 editMode 的变量,它决定了网格当时是否可以调整大小和可拖动) ),当我移动或调整网格项大小时,API 请求会不间断地发送。对于移动,它们都失败(可能是不正确的数据),但是对于调整大小,它们返回 200 OK。我不明白为什么要发送这些请求。

这些组件的外观如下:

小部件组件:

<grid-layout
 :layout.sync="layout"
 :col-num="colNum"
 :row-height="30"
 :is-draggable="editMode"
 :is-resizable="editMode"
 :vertical-compact="true"
 :use-css-transforms="true"
>
 <grid-item
  v-for="item in layout"
  :static="item.static"
  :x="item.x"
  :y="item.y"
  :w="item.w"
  :h="item.h"
  :i="item.i"
  :key="item.i"
  @resized="resizedEvent"
  @moved="movedEvent"
  style="touch-action: none"
 >
  <WidgetsExtended
   :edit-mode="editMode"
   :index="item.i"
  ></WidgetsExtended>
 </grid-item>
</grid-layout>

WidgetExtended 有一些表格,实际上显示在网格项中。对于这种情况并不重要。

<script setup>
import { ref } from "vue";
import { GridItem, GridLayout } from "vue3-grid-layout-next";

const emit = defineEmits(["updateLayout"]);

const props = defineProps({
  editMode: {
    type: Boolean,
    required: false,
    default: false,
  },
});

const layout = ref([]);
const colNum = ref(12);

function movedEvent(i, newX, newY) {
  emit("updateLayout", layout.value);
}

function resizedEvent(i, newH, newW, newHPx, newWPx) {
  emit("updateLayout", layout.value);
}
</script>

候选人页面:

<template>
  <div>
    <Widgets
      :edit-mode="editMode"
      @updateLayout="updateLayout"
    ></Widgets>
    <IconsEdit v-if="!editMode" @edit="editMode = true" />
    <IconsSave v-if="editMode" @save="save" />
  </div>
</template>

<script setup>
import { useCandidatesStore } from "~/stores/candidates";

const candidatesStore = useCandidatesStore();

const editMode = ref(false);
const newLayout = ref([]);
// function from store which sends API request
const { saveCandidatesLayout } = candidatesStore;

function save() {
  editMode.value = false;
  saveCandidatesLayout(newLayout.value);
}

function updateLayout(updatedLayout) {
  newLayout.value = updatedLayout;
}
</script>

候选人商店:

import { defineStore } from "pinia";
import { useFetch } from "#app";
import { useAuthStore } from "./auth";

const baseUrl = import.meta.env.VITE_API_KEY + "/hr/";

export const useCandidatesStore = defineStore("candidates", () => {
  const authStore = useAuthStore();

  function saveCandidatesLayout(body) {
    return useFetch(baseUrl + "layout/candidates", {
      method: "POST",
      headers: {
        Accept: "application/json",
        Authorization: "Bearer " + authStore.token,
      },
      body: body,
      onResponse({ request, response, options }) {
        // this part gets called non-stop, I tried to log everywhere and this is only part 
        return response._data;
      },
      onResponseError({ request, response, options }) {
        throw showError({
          statusCode: 401,
          statusMessage: "Error: " + error,
          fatal: true,
        });
      },
    });
  }

  return {
    saveCandidatesLayout
  };
});

我什至尝试检查开发工具(网络选项卡)中请求是从哪里发送的。目前还不清楚,它看起来像是来自某个库,并且它的根源在于 pointMove -> move 函数。这些请求的发起者是 ofetch.d438bb6f.mjs:206 (fetch)。

我不明白的是,当没有与之相关的功能可以做到这一点时,移动或调整网格项大小如何直接发出API请求。

javascript vue.js nuxt.js grid-layout usefetch
1个回答
1
投票

我发现问题了!感谢这篇文章https://github.com/nuxt/nuxt/issues/15741我意识到我正在向 useFetch 主体发送反应式属性,并且每次它发生变化时,都会重新发送请求。我刚刚使用 JSON.stringify(body) 并解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.