参考值“渗入”到组件的所有 v-for 实例中

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

Nuxt3项目,在所有组件中使用脚本设置。

我有一个卡组件,它处理它自己的数据库删除和删除的挂起状态。下面是删除按钮,具有待删除状态以在删除时显示微调器:

// in template of NoteCard
<button
@click.prevent="showConfirmModal = true"
v-if="!pendingDelete"
>
DELETE
</button>
<span v-else class="loading loading-spinner"></span>

我使用可组合项进行数据库操作,它从子组件本身调用并给出挂起状态:

// in script setup of NoteCard
const { dbDelete, pending: pendingDelete, error } = useDbDelete;

const deleteNote = async () => {
  await dbDelete("notes", props.note.id);
  if (!error.value) {
    emit("deleted");
  }
};

可组合项定义为:

//useDbDelete.js

const pending = ref(false);
const error = ref(null);
const result = ref(null);

const dbDelete = async (endpoint, id) => {
  pending.value = true;
  //delete from db
  try {
    await $fetch(`/api/${endpoint}/${id}/delete`, {
      method: "DELETE",
    });
    result.value = "Success";
  } catch (err) {
    error.value = err.message;
  }
  pending.value = false;
};

export default { dbDelete, result, pending, error };

在父级中,我为每个实例渲染此卡:

// in template of parent
<NoteCard
v-for="note in item?.notes"
:key="note.id"
/>

当我删除时,卡片的所有实例都会显示微调器。为什么是这样?每张卡不应该能够处理自己的pendingDelete状态吗?我知道,如果我在父级中处理这个挂起状态,我需要有唯一的值并维护这个状态的数组,但是由于组件的每个实例都在内部处理它,这不应该好吗?

我尝试将 v-for 移动到包裹组件的 div 中。没有用。

尝试使用索引而不是 ID 作为 :key,同样的问题。

nuxt.js vuejs3 nuxtjs3
1个回答
0
投票

像这样编写可组合项,

const pending = ref(false);
将在整个应用程序中共享。您需要将其包装在一个函数内并导出该函数以与其余函数隔离。并且您
return
想要在组件中使用的部分,而不是直接导出它们。

像这样:

export function useDbDelete() {
  const pending = ref(false);
  const error = ref(null);
  const result = ref(null);

  const dbDelete = async (endpoint, id) => {
    pending.value = true;
    //delete from db
    try {
      // await $fetch(`/api/${endpoint}/${id}/delete`, {
      //  method: 'DELETE',
      // });
      result.value = 'Success';
    } catch (err) {
      error.value = err.message;
    }
    setTimeout(() => (pending.value = false), 3000);
  };

  return { dbDelete, result, pending, error };
}

那么你只需要改变

NoteCard
中的定义即可(加上括号使其成为函数):

const { dbDelete, pending: pendingDelete, error } = useDbDelete();

此处快速演示:https://stackblitz.com/edit/github-cvre6j?file=app.vue

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