Skip to content

弹出确认 Popconfirm ​

赞助

点击元素,弹出气泡式的确认框

何时使用 ​

  • 目标元素的操作需要用户进一步的确认时,在目标元素附近弹出浮层提示,询问用户

基本使用 ​

Delete Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
const openChange = (open: boolean) => {
  console.log('open', open)
}
</script>
<template>
  <Popconfirm
    title="Are you sure delete this task ?"
    description="This will have other effects..."
    @ok="confirm"
    @cancel="cancel"
    @open-change="openChange"
  >
    <Button type="danger">Delete Confirm</Button>
  </Popconfirm>
</template>

隐藏取消按钮 ​

Hidden Cancel Btn
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
</script>
<template>
  <Popconfirm
    title="It's friendly reminder ..."
    :show-cancel="false"
    icon="info"
    @ok="confirm"
  >
    <Button type="primary">Hidden Cancel Btn</Button>
  </Popconfirm>
</template>

自定义样式 ​

Vue Amazing UI
Show Code
vue
<script setup lang="ts">
import { FireFilled } from '@ant-design/icons-vue'
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Popconfirm
    :max-width="280"
    :show-cancel="false"
    :title-style="{ fontSize: '16px', fontWeight: 'bold', color: '#1677ff' }"
    :description-style="{ color: '#fff' }"
    bg-color="#000"
    :tooltip-style="{ padding: '16px 18px', borderRadius: '12px' }"
    :icon-style="{ fontSize: '16px', paddingTop: '5px' }"
    ok-text="Awesome"
    :ok-props="{ shape: 'round' }"
    @ok="confirm"
    @cancel="cancel"
  >
    <template #title>
      <a href="https://themusecatcher.github.io/vue-amazing-ui/" target="_blank">Vue Amazing UI</a>
    </template>
    <template #description> An Amazing Vue3 UI Components Library </template>
    <template #icon>
      <FireFilled style="color: #d4380d" />
    </template>
    <Button type="primary">Vue Amazing UI</Button>
  </Popconfirm>
</template>

弹出位置 ​

通过 placement 指定方向;复合方向(如 topLeft)配合 arrowPointAtCenter 可让箭头指向触发元素中心,空间不足时 flip 会自动翻转


placement:
topLeft
top
topRight
bottomLeft
bottom
bottomRight
Adjust Placement
Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
const placements = ['topLeft', 'top', 'topRight', 'bottomLeft', 'bottom', 'bottomRight']
const placement = ref('top')
</script>
<template>
  <Flex vertical>
    <Space align="center">
      placement:
      <Segmented v-model:value="placement" :options="placements" />
    </Space>
    <Popconfirm
      :placement="placement"
      title="It's friendly reminder ..."
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Adjust Placement</Button>
    </Popconfirm>
  </Flex>
</template>

箭头指向 ​

设置 arrowPointAtCenter 后,箭头将指向目标元素中心,仅当 placement 为复合方向(如 topLeft)时生效


Align edge
Arrow points to center
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm placement="topLeft" title="Are you sure ?" @ok="confirm" @cancel="cancel">
      <Button type="primary">Align edge</Button>
    </Popconfirm>
    <Popconfirm placement="topLeft" arrow-point-at-center title="Are you sure ?" @ok="confirm" @cancel="cancel">
      <Button type="primary">Arrow points to center</Button>
    </Popconfirm>
  </Space>
</template>

自定义按钮 ​

Delete Confirm
Delete Confirm
Delete Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm
      title="Are you sure ?"
      ok-text="Yes"
      cancel-text="No"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="danger">Delete Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="Are you sure ?"
      ok-text="Yes"
      :ok-props="{ ghost: true }"
      cancel-text="No"
      :cancel-props="{ type: 'danger', ghost: true }"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="danger">Delete Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="Are you sure ?"
      ok-text="Yes"
      ok-type="danger"
      cancel-text="No"
      cancel-type="dashed"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="danger">Delete Confirm</Button>
    </Popconfirm>
  </Space>
</template>

预置四种图标 ​

Warning Confirm
Info Confirm
Success Confirm
Danger Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm
      title="Are you sure delete this task ?"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Warning Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="Are you sure delete this task ?"
      icon="info"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Info Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="Are you sure delete this task ?"
      icon="success"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Success Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="Are you sure delete this task ?"
      icon="danger"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Danger Confirm</Button>
    </Popconfirm>
  </Space>
</template>

自定义图标 ​

Delete Confirm
Notification Confirm
Show Code
vue
<script setup lang="ts">
import { h } from 'vue'
import { QuestionCircleFilled, SoundFilled } from '@ant-design/icons-vue'
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm
      title="Are you sure ?"
      :icon="() => h(QuestionCircleFilled, { style: 'color: #ff4d4f' })"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="danger">Delete Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="Are you sure ?"
      @ok="confirm"
      @cancel="cancel"
    >
      <template #icon>
        <SoundFilled style="color: #faad14" />
      </template>
      <Button type="primary">Notification Confirm</Button>
    </Popconfirm>
  </Space>
</template>

不同的触发方式 ​

默认点击触发器展开,再次点击触发器或点击浮层之外收起;click / contextmenu 触发时按 esc 也可关闭(与 文字提示 Tooltip 一致)


Click Me Confirm
Hover Me Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm
      title="It's friendly reminder ..."
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Click Me Confirm</Button>
    </Popconfirm>
    <Popconfirm
      title="It's friendly reminder ..."
      trigger="hover"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Hover Me Confirm</Button>
    </Popconfirm>
  </Space>
</template>

受控显示 ​

使用 v-model:open 控制显隐;openControl 为真时 trigger: hover 不再驱动显隐,显隐完全由 open 决定


Controlled: false
Toggle Open
Hover (openControl)
Toggle Open (openControl)
Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
const controlledOpen = ref(false)
const openControlOpen = ref(false)
</script>
<template>
  <Space vertical :gap="12">
    <Space>
      <Popconfirm v-model:open="controlledOpen" title="It's friendly reminder ..." @ok="confirm" @cancel="cancel">
        <Button>Controlled: {{ controlledOpen }}</Button>
      </Popconfirm>
      <Button type="primary" @click="controlledOpen = !controlledOpen">Toggle Open</Button>
    </Space>
    <Space>
      <Popconfirm
        v-model:open="openControlOpen"
        open-control
        trigger="hover"
        title="Controlled Only"
        @ok="confirm"
        @cancel="cancel"
      >
        <Button>Hover (openControl)</Button>
      </Popconfirm>
      <Button type="primary" @click="openControlOpen = !openControlOpen">Toggle Open (openControl)</Button>
    </Space>
  </Space>
</template>

自定义过渡动画时间 ​

Transition Duration 300ms
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Popconfirm title="Transition Duration 300ms" :transition-duration="300" @ok="confirm" @cancel="cancel">
    <Button type="primary">Transition Duration 300ms</Button>
  </Popconfirm>
</template>

延迟显示隐藏 ​

Delay 300ms Confirm
Delay 500ms Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm
      :show-delay="300"
      :hide-delay="300"
      title="Are you confirm ?"
      description="delay 300ms"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Delay 300ms Confirm</Button>
    </Popconfirm>
    <Popconfirm
      :show-delay="500"
      :hide-delay="500"
      title="Are you confirm ?"
      description="delay 500ms"
      @ok="confirm"
      @cancel="cancel"
    >
      <Button type="primary">Delay 500ms Confirm</Button>
    </Popconfirm>
  </Space>
</template>

隐藏后卸载 ​

设置 destroyOnHide 后,浮层在离开动画结束时卸载 DOM,再次显示时重新创建并定位;默认 false(元素常驻,仅切换显示)


Click (destroyOnHide)
Click (default)
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Space>
    <Popconfirm title="Are you sure ?" destroy-on-hide @ok="confirm" @cancel="cancel">
      <Button type="primary">Click (destroyOnHide)</Button>
    </Popconfirm>
    <Popconfirm title="Are you sure ?" @ok="confirm" @cancel="cancel">
      <Button>Click (default)</Button>
    </Popconfirm>
  </Space>
</template>

隐藏箭头 ​

Hide Arrow Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Popconfirm
    :arrow="false"
    title="My arrow is hidden"
    @ok="confirm"
    @cancel="cancel"
  >
    <Button type="primary">Hide Arrow Confirm</Button>
  </Popconfirm>
</template>

键盘与读屏 ​

面板语义为 alertdialog,可访问名称取标题;打开后焦点落在「确定」,Tab 在「取消 / 确定」之间移动,Esc 关闭,关闭后焦点归还触发元素(若关闭前焦点已被点到页面上其它位置,则不抢回)。触发器不再把面板内容作为描述朗读


Keyboard Confirm
Show Code
vue
<script setup lang="ts">
import { useMessage } from 'vue-amazing-ui'
const message = useMessage()
const confirm = (e: MouseEvent) => {
  console.log('confirm', e)
  message.success('Click on Yes')
}
const cancel = (e: MouseEvent) => {
  console.log('cancel', e)
  message.error('Click on No')
}
</script>
<template>
  <Popconfirm
    title="Are you sure delete this task ?"
    description="This will have other effects..."
    @ok="confirm"
    @cancel="cancel"
  >
    <Button type="primary">Keyboard Confirm</Button>
  </Popconfirm>
</template>

更多使用方式请参考 文字提示 Tooltip

APIs ​

Popconfirm Props ​

名称说明类型默认值
title弹出确认框的标题stringundefined
titleStyle设置标题的样式CSSProperties{}
description弹出确认框的内容描述stringundefined
descriptionStyle设置内容描述的样式CSSProperties{}
tooltipStyle设置弹出提示的样式CSSProperties{}
icon自定义弹出确认框 Icon 图标,预置四种类型,或 prop 支持 VNode / 渲染函数;插槽形态请用同名 #icon 插槽'success' | 'info' | 'warning' | 'danger' | VNode | (() => VNode)'warning'
iconStyle设置 Icon 图标的样式,一般不需要设置,主要用于自定义 Icon 图标时CSSProperties{}
cancelText取消按钮文字string'取消'
cancelType取消按钮类型'default' | 'reverse' | 'primary' | 'danger' | 'dashed' | 'text' | 'link''default'
cancelProps取消按钮 props,优先级高于 cancelType,参考 Button PropsButtonProps{}
okText确认按钮文字string'确定'
okType确认按钮类型'default' | 'reverse' | 'primary' | 'danger' | 'dashed' | 'text' | 'link''primary'
okProps确认按钮 props,优先级高于 okType,参考 Button PropsButtonProps{}
showCancel是否显示取消按钮booleantrue

与 Tooltip 的差异 ​


Popconfirm 完整继承 Tooltip Props 及对应的 Events / Methods(类型 PopconfirmProps 即 Omit<TooltipProps, …> 叠加自有字段),<Popconfirm trigger="hover"> 这类写法与 <Tooltip trigger="hover"> 等价。

下表只列与 Tooltip 不同的部分,其余属性、事件与方法见 文字提示 Tooltip:

名称与 Tooltip 的差异
tooltipStyle作用于卡片容器,内置 padding: 12px / border-radius: 8px 与左对齐文案,可覆盖
tooltipClass可用,类名落在卡片容器上(与 tooltipStyle 同节点)
contentClass / contentStyle不可用(类型上已从 PopconfirmProps 剔除),请改用 titleStyle / descriptionStyle 或对应插槽
tooltip不可用:卡片内容由本组件渲染,请改用 title / description 或同名插槽
content不可用:确认框内容由 title / description 提供,传入后不显示
trigger默认 'click'(Tooltip 为 'hover');click 再次点击触发器收起
keyboard默认 true(Tooltip 为 false)
maxWidth默认 'auto'(Tooltip 为 240)
bgColor默认 var(--va-bg-elevated-color),与浮层底板同色(Tooltip 为 var(--va-bg-spotlight-color))
transitionDuration默认 200(Tooltip 为 100)
tooltipRole / describedBy默认 'alertdialog' / false(Tooltip 为 'tooltip' / true):面板是待操作内容而非触发器的描述,无需传入
anchor可用,但传入后不再渲染触发包裹层,触发元素需由使用方自行提供

Slots ​

名称说明用法
icon自定义图标v-slot:icon
title自定义弹出确认框的标题v-slot:title
description自定义弹出确认框的内容描述v-slot:description
cancelText自定义取消按钮文字v-slot:cancelText
okText自定义确认按钮文字v-slot:okText
default自定义内容v-slot:default

Events ​

名称说明类型
cancel点击取消的回调(e: Event) => void
ok点击确认的回调(e: Event) => void
openChange显示隐藏的回调(open: boolean) => void
animationend显示隐藏动画结束时的回调(open: boolean) => void

Released under the MIT License.