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,同样的问题。
像这样编写可组合项,
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