Skip to content

Popover 弹出框

Popover 在内容周围弹出一些隐藏的信息。Popover 里面没什么内置样式,在里面填什么主要靠你了。

基础用法

<template>
  <sp-popover trigger="hover" content="欲穷千里目,更上一层楼">
    <template #reference>
      <sp-button>hover</sp-button>
    </template>
  </sp-popover>
  <sp-popover trigger="click" content="欲穷千里目,更上一层楼">
    欲穷千里目,更上一层楼
    <template #reference>
      <sp-button>click</sp-button>
    </template>
  </sp-popover>
  <sp-popover
    :visible="visible"
    trigger="hover"
    content="受控情况下,可以通过监听 clickoutside 判断是否点击外部元素"
  >
    <template #reference>
      <sp-button @click="visible = !visible"
        >受控:{{ !visible ? '关闭中' : '展开中' }}</sp-button
      >
    </template>
  </sp-popover>
</template>
<script lang="ts" setup>
import { ref } from 'vue'

const visible = ref(false)
</script>

位置

<template>
  <div class="popover-placement-container top">
    <sp-popover placement="top-start" v-bind="bind">
      <template #reference>
        <sp-button>top-start</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="top" v-bind="bind">
      <template #reference>
        <sp-button>top</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="top-end" v-bind="bind">
      <template #reference>
        <sp-button>top-end</sp-button>
      </template>
    </sp-popover>
  </div>
  <div class="popover-placement-container start">
    <sp-popover placement="left-start" v-bind="bind">
      <template #reference>
        <sp-button>left-start</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="right-start" v-bind="bind">
      <template #reference>
        <sp-button>right-start</sp-button>
      </template>
    </sp-popover>
  </div>
  <div class="popover-placement-container start">
    <sp-popover placement="left" v-bind="bind">
      <template #reference>
        <sp-button>left</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="right" v-bind="bind">
      <template #reference>
        <sp-button>right</sp-button>
      </template>
    </sp-popover>
  </div>
  <div class="popover-placement-container start">
    <sp-popover placement="left-end" v-bind="bind">
      <template #reference>
        <sp-button>left-end</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="right-end" v-bind="bind">
      <template #reference>
        <sp-button>right-end</sp-button>
      </template>
    </sp-popover>
  </div>
  <div class="popover-placement-container top">
    <sp-popover placement="bottom-start" v-bind="bind">
      <template #reference>
        <sp-button>bottom-start</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="bottom" v-bind="bind">
      <template #reference>
        <sp-button>bottom</sp-button>
      </template>
    </sp-popover>
    <sp-popover placement="bottom-end" v-bind="bind">
      <template #reference>
        <sp-button>bottom-end</sp-button>
      </template>
    </sp-popover>
  </div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'

const bind = reactive({
  content: '白日依山尽,黄河入海流。欲穷千里目,更上一层楼。',
  trigger: 'hover',
  'max-width': '190px',
})
</script>

<style>
.popover-placement-container {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  &:last-child {
    margin-bottom: 0;
  }
  &.top {
    justify-content: center;
  }
  &.start {
    justify-content: space-between;
  }
}
</style>

延迟

openDelay 延迟显示(在多个 popover 下很好用),closeDelay 延迟关闭

<template>
  <sp-popover
    content="白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"
    :open-delay="500"
    :close-delay="500"
    trigger="hover"
  >
    <template #reference>
      <sp-button>500ms后打开,500ms后关闭</sp-button>
    </template>
  </sp-popover>
</template>

不要箭头

<template>
  <sp-popover
    content="白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"
    trigger="hover"
    :show-arrow="false"
  >
    <template #reference>
      <sp-button>不要箭头</sp-button>
    </template>
  </sp-popover>
</template>

宽度

<template>
  <sp-popover
    max-width="100px"
    trigger="hover"
    content="欲穷千里目,更上一层楼"
  >
    <template #reference>
      <sp-button>最大宽度100px</sp-button>
    </template>
  </sp-popover>
  <sp-popover width="200px" trigger="hover" content="欲穷千里目,更上一层楼">
    欲穷千里目,更上一层楼
    <template #reference>
      <sp-button>宽度200px</sp-button>
    </template>
  </sp-popover>
  <sp-popover
    trigger="hover"
    min-width="300px"
    content="欲穷千里目,更上一层楼"
  >
    <template #reference>
      <sp-button>最小宽度300px</sp-button>
    </template>
  </sp-popover>
</template>

自定义动画

<template>
  <sp-popover
    width="190px"
    trigger="hover"
    content="白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"
    transition="zoom-in-top"
  >
    <template #reference>
      <sp-button>自定义动画效果</sp-button>
    </template>
  </sp-popover>
</template>

<style>
.zoom-in-top-enter-active,
.zoom-in-top-leave-active {
  opacity: 1;
  transform: scaleY(1);
  transition: all 0.3s ease;
  transform-origin: center top;
}
.zoom-in-top-enter-from,
.zoom-in-top-leave-active {
  opacity: 0;
  transform: scaleY(0);
}
</style>

API

属性名说明类型默认值
trigger触发方式'hover' | 'click' | 'manual''click'
content内容,插槽优先string
disabled禁止弹窗booleanfalse
visible受控显示boolean | nullnull
placement显示位置Placement'bottom'
strategy弹窗定位方式Strategy'absolute'
effect主题'dark' | 'light''light'
offset浮层偏移量number8
showArrow是否显示箭头booleantrue
maxWidth最大宽度,CSS 值number | string
minWidth最小宽度,CSS 值number | string
width宽度,CSS 值number | string
transition动画名string'sp-fade-in-scale-up'
closeDelay关闭延迟number150
openDelay打开延迟number0
zIndexzIndex 值numbernull
autoUpdate是否自动更新弹窗位置,AutoUpdateOptions | booleanfalse

AutoUpdateOptions

  1. ancestorResize 当溢出祖先元素的大小调整时是否更新位置
  2. elementResize 当参考元素或浮动元素调整大小时是否更新位置
  3. layoutShift 如果由于布局偏移而导致参考元素在屏幕上移动,是否更新浮动元素的位置。
  4. animationFrame 是否在需要时在每个动画帧上更新浮动元素的位置。虽然已针对性能进行了优化,但在以下情况下应谨慎使用

插槽

插槽名说明
reference触发元素,请使用一个元素
default弹窗内容

事件

事件名说明参数
update:visible修改显示状态时触发boolean
clickoutside点击外部区域触发
before-enter显示前触发
after-enter显示后触发
before-leave消失前触发
after-leave消失后触发