You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Nuxt中通过父组件按钮控制shadcn-vue的Sheet组件开关

解决方案

要实现将Sheet的触发按钮放在父组件头部,同时控制Sheet的打开/关闭状态,你可以通过受控模式来管理Sheet的状态,具体步骤如下:

1. 父组件中添加状态管理

在父组件里创建一个响应式变量,用来跟踪Sheet的打开状态:

<template>
  <div>
    <header>
      <!-- 点击头部按钮切换Sheet状态 -->
      <button 
        class="row-start-2 hidden md-max:block" 
        type="button"
        @click="isSheetOpen = !isSheetOpen"
      >
        <img src="/images/icons/hamburger.svg" alt="menu icon" />
      </button>
    </header>
    <!-- 使用v-model绑定Sheet的打开状态 -->
    <ItemSheet v-model:open="isSheetOpen" />
  </div>
</template>

<script setup>
import ItemSheet from '@/components/ItemSheet.vue';
import { ref } from 'vue';

// 初始化Sheet为关闭状态
const isSheetOpen = ref(false);
</script>

2. 修改子组件(ItemSheet)支持受控模式

更新子组件,接收父组件传递的open属性,并在Sheet需要关闭时向父组件发送状态更新事件:

<template>
  <!-- 绑定open属性,并监听update:open事件 -->
  <Sheet :open="open" @update:open="$emit('update:open', $event)">
    <!-- 移除原有的SheetTrigger,改用父组件的按钮触发 -->
    <SheetContent>
      <SheetHeader>
        <SheetTitle>Are you absolutely sure?</SheetTitle>
        <SheetDescription>
          This action cannot be undone. This will permanently delete your account
          and remove your data from our servers.
        </SheetDescription>
      </SheetHeader>
      <!-- 可选:在Sheet内部添加关闭按钮 -->
      <SheetClose as-child>
        <button type="button" class="mt-4">取消</button>
      </SheetClose>
    </SheetContent>
  </Sheet>
</template>

<script setup>
// 定义接收的open属性
defineProps({
  open: {
    type: Boolean,
    required: true
  }
})

// 定义发送状态更新的事件
defineEmits(['update:open'])
</script>

关键说明

  • 受控模式:通过v-model:open将父组件的状态与Sheet组件绑定,父组件完全掌控Sheet的打开/关闭状态。
  • 内置关闭行为:Sheet组件的默认关闭逻辑(点击遮罩层、按下ESC键)会自动触发update:open事件,同步更新父组件的状态,无需额外处理。
  • 自定义关闭按钮:如果需要在Sheet内部添加关闭按钮,使用SheetClose组件即可,它会自动触发关闭逻辑并通知父组件。

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:00:03