Shadcn-vue Dialog问题:点击编辑/删除时两个弹窗同时弹出
Shadcn-vue点击下拉菜单时两个Dialog同时弹出的解决方案
问题概览
使用Shadcn-vue的Dialog组件时,点击表格下拉菜单中的Edit或Delete选项,credentials-dialog和delete-dialog两个弹窗会同时弹出,用v-if控制也无效。
问题根源
Shadcn-vue的Dialog组件通过上下文关联工作:同一个<Dialog>父容器下的所有DialogContent(也就是你的两个自定义弹窗)会被该容器内的任意DialogTrigger触发。你把两个自定义弹窗都放在了外层的<Dialog>标签里,导致点击任何一个DialogTrigger都会同时激活两个弹窗。v-if只能控制弹窗是否渲染,但只要在同一个Dialog上下文里,触发逻辑还是会关联所有存在的弹窗内容,所以没用。
解决方法
方法1:移除外层Dialog,手动控制弹窗显示
直接去掉包裹整个表和弹窗的外层<Dialog>,改用自定义弹窗的内置方法控制显示,不需要用DialogTrigger:
<Table v-if="credentialsList"> <TableCell> <DropdownMenu> <DropdownMenuTrigger as-child> <Button aria-haspopup="true" size="icon" variant="ghost" class="dark:hover:bg-transparent" > <EllipsisVertical class="h-4 w-4" /> <span class="sr-only">Toggle menu</span> </Button> </DropdownMenuTrigger> <DropdownMenuContent align="end"> <DropdownMenuItem class="cursor-pointer" @click="credentialsDialogRef.editCredential(credential); credentialsDialogRef.open()" > {{ $t("message.common.edit") }} </DropdownMenuItem> <DropdownMenuItem @click="deleteDialogRef.open(credential)" class="cursor-pointer w-full" > Delete </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </TableCell> </Table> <credentials-dialog ref="credentialsDialogRef" /> <delete-dialog ref="deleteDialogRef" />
注:这里假设你的自定义弹窗组件(
credentials-dialog和delete-dialog)内部有open这类控制弹窗显示的方法,根据实际组件逻辑调整即可。
方法2:给每个弹窗独立分配Dialog上下文
如果一定要使用DialogTrigger,需要让每个DialogTrigger和对应的弹窗属于独立的<Dialog>容器:
<Table v-if="credentialsList"> <TableCell> <DropdownMenu> <DropdownMenuTrigger as-child> <Button aria-haspopup="true" size="icon" variant="ghost" class="dark:hover:bg-transparent" > <EllipsisVertical class="h-4 w-4" /> <span class="sr-only">Toggle menu</span> </Button> </DropdownMenuTrigger> <DropdownMenuContent align="end"> <!-- 编辑弹窗的独立Dialog上下文 --> <Dialog> <DialogTrigger class="w-full"> <DropdownMenuItem class="cursor-pointer" @click="credentialsDialogRef.editCredential(credential)" > {{ $t("message.common.edit") }} </DropdownMenuItem> </DialogTrigger> <credentials-dialog slot="content" ref="credentialsDialogRef" /> </Dialog> <!-- 删除弹窗的独立Dialog上下文 --> <Dialog> <DialogTrigger class="w-full"> <DropdownMenuItem @click="handleDelete(credential)" class="cursor-pointer w-full" > Delete </DropdownMenuItem> </DialogTrigger> <delete-dialog slot="content" ref="deleteDialogRef" /> </Dialog> </DropdownMenuContent> </DropdownMenu> </TableCell> </Table>
注:如果你的自定义弹窗内部已经包含了
DialogContent,需要确保外层的<Dialog>和内部结构正确联动,或者调整弹窗组件的slot结构。
内容的提问来源于stack exchange,提问作者Faveq
相关产品推荐
相关产品推荐

