---
title: "SigmaPopover"
description: "锚定到节点的常驻浮层，内部可交互，开合状态由 v-model:open 控制。"
canonical_url: "https://sigma.mhaibaraai.cn/docs/components/popover"
---
# SigmaPopover

> 锚定到节点的常驻浮层，内部可交互，开合状态由 v-model:open 控制。

## 用法

与 `SigmaTooltip` 的区别在「常驻」与「可交互」：提示层跟着指针走、鼠标穿透，浮层则停在那里，`.sigma-popover` 把 `pointer-events` 恢复成了 `auto`，里面的按钮、输入框、滚动区域都能用。

### `node`

锚定的节点 key，为空时浮层不显示：

```vue [PopoverNodeExample.vue]
<script setup lang="ts">
const node = shallowRef<string | null>('b')

const { data } = await useFetch('/api/small.json')
</script>

<template>
  <SigmaGraph
    :data="data"
    @click-node="({ node: key }) => (node = key)"
    @click-stage="() => (node = null)"
  >
    <SigmaPopover :node="node">
      <template #default="{ attributes }">
        <strong>{{ attributes.label }}</strong>
      </template>
    </SigmaPopover>
  </SigmaGraph>
</template>
```

节点被隐藏或从图上移除时，浮层跟着 `SigmaOverlay` 一起自动隐藏。

### `open`

`v-model:open` 控制开合，默认 `true`。显示需要 `open` 为真**且** `node` 非空，两个开关互不干扰——`node` 绑选中项，`open` 绑用户的关闭动作：

```vue [PopoverOpenExample.vue]
<script setup lang="ts">
const node = shallowRef<string | null>('c')
const open = ref(true)

watch(node, (key) => {
  if (key) {
    open.value = true
  }
})

const { data } = await useFetch('/api/small.json')
</script>

<template>
  <SigmaGraph
    :data="data"
    @click-node="({ node: key }) => (node = key)"
    @click-stage="() => (node = null)"
  >
    <SigmaPopover v-model:open="open" :node="node">
      <template #default="{ attributes, close }">
        <strong>{{ attributes.label }}</strong>
        <UButton size="xs" label="关闭" class="ml-2" @click="close" />
      </template>
    </SigmaPopover>

    <SigmaControls>
      <UButton :label="open ? '关闭浮层' : '打开浮层'" @click="open = !open" />
    </SigmaControls>
  </SigmaGraph>
</template>
```

> [!NOTE]
> 
> node
> 
>  变化不会自动把 
> 
> open
> 
>  拨回来。换节点时上一次的关闭仍然生效，所以示例里 
> 
> watch(node, ...)
> 
>  显式置回 
> 
> true
> 
> ；不写 
> 
> v-model:open
> 
>  时浮层的显隐完全跟随 
> 
> node
> 
> 。

### `offset`

相对锚点的像素偏移，默认 `[0, -16]`。`.sigma-popover` 的 `translate: -50% -100%` 负责水平居中与底边贴合，`offset` 负责让开节点半径——节点越大，需要的负向 y 越多：

```vue [PopoverOffsetExample.vue]
<script setup lang="ts">
const props = withDefaults(defineProps<{ offsetY?: number | string }>(), { offsetY: -16 })

const offset = computed<[number, number]>(() => [0, Number(props.offsetY)])

const { data } = await useFetch('/api/small.json')
</script>

<template>
  <SigmaGraph :data="data">
    <SigmaPopover node="b" :offset="offset">
      <template #default="{ attributes }">
        <strong>{{ attributes.label }}</strong>
      </template>
    </SigmaPopover>
  </SigmaGraph>
</template>
```

## 示例

### 默认插槽

插槽以 `{ node, attributes, close }` 暴露锚点。插槽只在浮层可见时渲染，因此 `node` 不会是 `null`；`attributes` 在节点已被移除时为 `{}`；`close()` 就是把 `open` 置为 `false`，供插槽内的关闭按钮直接调用，接管外观时不必自己往上传状态。

典型接法是配 `useSigmaSelection()`，点节点开详情、详情按需加载：

```vue [PopoverSlotExample.vue]
<script setup lang="ts">
const { data } = await useFetch('/api/data.json')
</script>

<template>
  <SigmaGraph :data="data">
    <PopoverSlotPanel />
  </SigmaGraph>
</template>
```

```vue [PopoverSlotPanel.vue]
<script setup lang="ts">
const { selected } = useSigmaSelection()
const open = ref(true)
</script>

<template>
  <SigmaPopover v-model:open="open" :node="selected">
    <template #default="{ node, attributes, close }">
      <strong>{{ attributes.label ?? node }}</strong>
      <button type="button" @click="close">
        ×
      </button>
    </template>
  </SigmaPopover>
</template>
```

> [!NOTE]
> 
> useSigmaSelection()
> 
>  与 
> 
> SigmaPopover
> 
>  都要在 
> 
> SigmaGraph
> 
>  子树内，所以消费上下文的这一层总是独立组件，而不是写在页面外壳里。

## API

### Props

```ts
/**
 * Props for the SigmaPopover component
 */
interface SigmaPopoverProps {
  /**
   * 锚定的节点。为空时不显示
   * @default null
   */
  node?: null | string | undefined;
  /**
   * 相对锚点的像素偏移 `[x, y]`
   * @default [0, -16]
   */
  offset?: [number, number] | undefined;
  /**
   * @default true
   */
  open?: boolean | undefined;
}
```

### Emits

```ts
/**
 * Emitted events for the SigmaPopover component
 */
interface SigmaPopoverEmits {
  update:open: (payload: [value: boolean]) => void;
}
```

### Slots

```ts
/**
 * Slots for the SigmaPopover component
 */
interface SigmaPopoverSlots {
  default(): any;
}
```


## Sitemap

See the full [sitemap](https://sigma.mhaibaraai.cn/sitemap.md) for all pages.
