Skip to content

Dropdown 下拉菜单

将动作或菜单折叠到下拉菜单中。

基础用法

悬停在下拉菜单上以展开更多操作。

通过组件 slot 来设置下拉触发的元素以及需要通过具名插槽 dropdown 来设置下拉菜单内容。默认情况下, 只需要悬停在触发菜单的元素上即可, 无需点击也会显示下拉菜单。

<template>
  <px-dropdown>
    <span class="flex items-center text-12 color-#209cee">
      Dropdown List
      <px-icon
        icon="angle-down-solid"
        color="var(--px-color-primary)"
        class="mt-3 ml-5"
      />
    </span>
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item disabled>Action 4</px-dropdown-item>
      <px-dropdown-item divided>Action 5</px-dropdown-item>
    </template>
  </px-dropdown>
</template>

位置

属性继承自 Tooltip 组件, 支持 12 个方向, 详情请查看 Tooltip 组件。

<template>
  <div class="dropdown-base-box">
    <div class="row center">
      <px-dropdown placement="top-start">
        <px-button>top-start</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="top">
        <px-button>top</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="top-end">
        <px-button>top-end</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>
    </div>

    <div class="row">
      <px-dropdown placement="left-start">
        <px-button>left-start</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="right-start">
        <px-button>right-start</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>
    </div>

    <div class="row">
      <px-dropdown placement="left">
        <px-button class="mt-3 mb-3">left</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="right">
        <px-button>right</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>
    </div>

    <div class="row">
      <px-dropdown placement="left-end">
        <px-button>left-end</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="right-end">
        <px-button>right-end</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>
    </div>

    <div class="row center">
      <px-dropdown placement="bottom-start">
        <px-button>bottom-start</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="bottom">
        <px-button>bottom</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>

      <px-dropdown placement="bottom-end">
        <px-button>bottom-end</px-button>
        <template #dropdown>
          <px-dropdown-item>Action 1</px-dropdown-item>
          <px-dropdown-item>Action 2</px-dropdown-item>
          <px-dropdown-item>Action 3</px-dropdown-item>
        </template>
      </px-dropdown>
    </div>
  </div>
</template>

<style>
.dropdown-base-box .row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.dropdown-base-box .center {
  justify-content: center;
}

.dropdown-base-box .row .px-dropdown {
  margin-top: 10px;
}
</style>

触发对象

可使用按钮触发下拉菜单。

设置 split-button 属性来让触发下拉元素呈现为按钮组, 左边是功能按钮, 右边是触发下拉菜单的按钮, 设置为 true 即可。如果你想要在第三和第四个选项之间添加一个分隔符, 你只需要为第四个选项添加一个 divided 的属性。

<template>
  <div class="flex flex-wrap items-center">
    <px-dropdown>
      <px-button type="primary">
        Dropdown List<px-icon
          icon="angle-down-solid"
          color="var(--px-color-white)"
          class="translate-y-1 ml-5"
        />
      </px-button>
      <template #dropdown>
        <px-dropdown-item>Action 1</px-dropdown-item>
        <px-dropdown-item>Action 2</px-dropdown-item>
        <px-dropdown-item>Action 3</px-dropdown-item>
        <px-dropdown-item>Action 4</px-dropdown-item>
        <px-dropdown-item>Action 5</px-dropdown-item>
      </template>
    </px-dropdown>
    <px-dropdown split-button type="primary" @click="handleClick">
      Dropdown List
      <template #dropdown>
        <px-dropdown-item>Action 1</px-dropdown-item>
        <px-dropdown-item>Action 2</px-dropdown-item>
        <px-dropdown-item>Action 3</px-dropdown-item>
        <px-dropdown-item divided>Action 4</px-dropdown-item>
        <px-dropdown-item>Action 5</px-dropdown-item>
      </template>
    </px-dropdown>
  </div>
</template>

<script lang="ts" setup>
const handleClick = () => {
  // eslint-disable-next-line no-alert
  alert('button click')
}
</script>

<style scoped>
.px-dropdown + .px-dropdown {
  margin-left: 15px;
}
.px-dropdown-link {
  cursor: pointer;
  color: var(--px-color-primary);
  display: flex;
  align-items: center;
}
</style>

触发方式

可以配置点击激活或者悬停激活。

trigger 属性设置为 click 即可, 默认为 hover

<script setup lang="ts">
import { type DropdownItemProps } from '@mmt817/pixel-ui'

const items: DropdownItemProps[] = [
  { command: '1', label: 'Action 1' },
  { command: '2', label: 'Action 2' },
  { command: '3', label: 'Action 3', disabled: true },
  { command: '4', label: 'Action 4', divided: true }
]
</script>

<template>
  <div class="flex flex-wrap">
    <div class="flex-1">
      <div class="desc">hover</div>
      <px-dropdown :items="items">
        <span class="dropdown-link">
          Dropdown List
          <px-icon
            icon="angle-down-solid"
            color="var(--px-color-primary)"
            class="translate-y-2"
          />
        </span>
      </px-dropdown>
    </div>
    <div class="flex-1">
      <div class="desc">click</div>
      <px-dropdown :items="items" trigger="click">
        <span class="dropdown-link">
          Dropdown List
          <px-icon
            icon="angle-down-solid"
            color="var(--px-color-primary)"
            class="translate-y-2"
          />
        </span>
      </px-dropdown>
    </div>
    <div class="flex-1">
      <div class="desc">contextmenu</div>
      <px-dropdown :items="items" trigger="contextmenu">
        <span class="dropdown-link">
          Dropdown List
          <px-icon
            icon="angle-down-solid"
            color="var(--px-color-primary)"
            class="translate-y-2"
          />
        </span>
      </px-dropdown>
    </div>
  </div>
</template>

<style scoped>
.desc {
  display: block;
  color: var(--px-text-color-secondary);
  font-size: 10px;
  margin-bottom: 20px;
}
.dropdown-link {
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: 12px;
  color: var(--px-color-primary);
  i {
    margin-left: 8px;
  }
}
</style>

禁用状态

可以通过设置 disabled 属性来禁用下拉菜单。

<script setup lang="ts">
import { type DropdownItemProps } from '@mmt817/pixel-ui'

const items: DropdownItemProps[] = [
  { command: '1', label: 'Action 1' },
  { command: '2', label: 'Action 2' },
  { command: '3', label: 'Action 3', disabled: true },
  { command: '4', label: 'Action 4', divided: true }
]
</script>

<template>
  <div class="flex flex-wrap">
    <div class="flex-1">
      <div class="desc">disabled</div>
      <px-dropdown :items="items" disabled>
        <span class="dropdown-link">
          Dropdown List
          <px-icon icon="angle-down-solid" />
        </span>
      </px-dropdown>
    </div>
    <div class="flex-1">
      <div class="desc">undisabled</div>
      <px-dropdown :items="items">
        <span class="dropdown-link">
          Dropdown List
          <px-icon icon="angle-down-solid" color="var(--px-color-primary)" />
        </span>
      </px-dropdown>
    </div>
  </div>
</template>

<style scoped>
.desc {
  display: block;
  color: var(--px-text-color-secondary);
  font-size: 12px;
  margin-bottom: 20px;
}
.dropdown-link {
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: 12px;
  color: var(--px-color-primary);
  i {
    margin-left: 8px;
  }
}
</style>

菜单隐藏方式

可以通过 hide-on-click 属性来配置。

下拉菜单默认在点击菜单项后会被隐藏, 将 hide-on-click 设置为 false 即可关闭此功能。

<template>
  <px-dropdown :hide-on-click="false">
    <span class="px-dropdown-link">
      Dropdown List
      <px-icon
        icon="angle-down-solid"
        color="var(--px-color-primary)"
        class="translate-y-1 ml-5"
      />
    </span>
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item disabled>Action 4</px-dropdown-item>
      <px-dropdown-item divided>Action 5</px-dropdown-item>
      <px-dropdown-item divided>Action 6</px-dropdown-item>
    </template>
  </px-dropdown>
</template>

<style scoped>
.px-dropdown + .px-dropdown {
  margin-left: 15px;
}
.px-dropdown-link {
  cursor: pointer;
  color: var(--px-color-primary);
  font-size: 12px;
  display: flex;
  align-items: center;
}
</style>

指令事件

点击菜单项后会触发事件, 用户可以通过相应的菜单项 key 进行不同的操作。

<template>
  <px-dropdown @command="handleCommand">
    <span class="px-dropdown-link">
      Dropdown List
      <px-icon
        icon="angle-down-solid"
        color="var(--px-color-primary)"
        class="translate-y-1 ml-5"
      />
    </span>
    <template #dropdown>
      <px-dropdown-item command="a">Action 1</px-dropdown-item>
      <px-dropdown-item command="b">Action 2</px-dropdown-item>
      <px-dropdown-item command="c">Action 3</px-dropdown-item>
      <px-dropdown-item command="d" disabled>Action 4</px-dropdown-item>
      <px-dropdown-item command="e" divided>Action 5</px-dropdown-item>
    </template>
  </px-dropdown>
</template>

<script lang="ts" setup>
import { PxMessage, messageTypes } from '@mmt817/pixel-ui'
const handleCommand = (command: string | number | object) => {
  PxMessage({
    message: `click on item ${command}`,
    type: messageTypes[Math.floor(Math.random() * messageTypes.length)]
  })
}
</script>

<style scoped>
.px-dropdown-link {
  cursor: pointer;
  color: var(--px-color-primary);
  font-size: 12px;
  display: flex;
  align-items: center;
}
</style>

下拉方式

您可以手动使用 手动打开手动关闭下拉菜单以打开或关闭

<script setup lang="ts">
import type { DropdownItemProps, DropdownInstance } from '@mmt817/pixel-ui'
import { ref } from 'vue'

const items: DropdownItemProps[] = [
  { command: '1', label: 'Action 1' },
  { command: '2', label: 'Action 2' },
  { command: '3', label: 'Action 3', disabled: true },
  { command: '4', label: 'Action 4', divided: true }
]
const dropdownRef = ref<DropdownInstance>()
</script>

<template>
  <px-button @click="() => dropdownRef?.open()">open</px-button>
  <px-button @click="() => dropdownRef?.close()">close</px-button>
  <br />
  <px-dropdown ref="dropdownRef" :items="items" trigger="click">
    <span class="dropdown-link">
      Dropdown List
      <px-icon
        icon="angle-down-solid"
        color="var(--px-color-primary)"
        class="translate-y-2"
      />
    </span>
  </px-dropdown>
</template>

<style scoped>
.dropdown-link {
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: 12px;
  color: var(--px-color-primary);
  margin-top: 20px;
  i {
    margin-left: 8px;
  }
}
</style>

尺寸

Dropdown 组件提供除了默认值以外的三种尺寸, 可以在不同场景下选择合适的尺寸。

使用 size 属性配置尺寸, 可选的尺寸大小有: large, default, small

<template>
  <px-dropdown size="large" split-button type="sakura">
    Large
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item>Action 4</px-dropdown-item>
    </template>
  </px-dropdown>

  <px-dropdown split-button type="success">
    Default
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item>Action 4</px-dropdown-item>
    </template>
  </px-dropdown>

  <px-dropdown size="small" split-button type="warning">
    Small
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item>Action 4</px-dropdown-item>
    </template>
  </px-dropdown>
</template>

<style scoped>
.px-dropdown + .px-dropdown {
  margin-left: 15px;
}
</style>

主题

Dropdown 组件属性大多继承自 Tooltip 组件, 同样内置了两个主题: lightdark

TIP

要使用自定义主题, 您必须知道您的工具提示在哪里渲染, 如果您的工具提示被呈现为根元素, 您将需要全局设置css规则。

设置自定义主题时, 需要同时修改弹出箭头和内容样式, 具体设置见下方 demo-preview

由于组件库祖宗之法基于 css houdini paintWorklet, 像素盒子大部分基于 pixelbox 渲染, 当前仅提供纯色主题, 如果希望渲染线性渐变, 等待后续升级

Dropdown 组件设置 inheritAttrs: false, 截断 v-bind="$attrs", 设置自定义属性需要使用样式穿透 ::v-deep

通过设置 effect 来修改主题, 默认为 light

<template>
  <px-dropdown split-button type="primary">
    Light
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item divided>Action 4</px-dropdown-item>
      <px-dropdown-item>Action 5</px-dropdown-item>
    </template>
  </px-dropdown>
  <px-dropdown split-button type="success" effect="dark">
    Drak
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item divided>Action 4</px-dropdown-item>
      <px-dropdown-item>Action 5</px-dropdown-item>
    </template>
  </px-dropdown>
  <px-dropdown split-button type="warning" effect="customized">
    Customized
    <template #dropdown>
      <px-dropdown-item>Action 1</px-dropdown-item>
      <px-dropdown-item>Action 2</px-dropdown-item>
      <px-dropdown-item>Action 3</px-dropdown-item>
      <px-dropdown-item divided>Action 4</px-dropdown-item>
      <px-dropdown-item>Action 5</px-dropdown-item>
    </template>
  </px-dropdown>
</template>
<style scoped>
.px-dropdown + .px-dropdown {
  margin-left: 15px;
}
:deep(.px-tooltip__popper.is-customized) {
  --px-bg-color: #9fe597;
  --px-border-color: #9fe597;
  --px-popover-text-color: red;

  #arrow::before {
    --px-popover-bg-color: #9fe597;
    --px-popover-border-color: #9fe597;
  }
}

:deep(.is-customized .divided-placeholder) {
  border-top-color: var(--px-color-white);
}
</style>

API_Table插件测试

DANGER

该插件基于 markdown-it 开发, 解析组件 types.ts 文件生成 API 表格, 测试中

Props

NameDescriptionTypeDefault
type菜单按钮类型enumbase
size菜单按钮尺寸enumdefault
items菜单项DropdownItemProps[][]
disabled菜单是否禁用booleanfalse
trigger触发方式enumhover
placement弹出位置enumbottom
hideOnClick点击菜单项时是否隐藏下拉菜单booleantrue
splitButtonpanel触发元素是否为按钮booleanfalse
popperOptionspopperjs 配置Partial<Options>{}
effect主题样式enumlight
transition过渡动画stringfade
showTimeout显示延时number150
hideTimeout隐藏延时number150

Events

NameDescriptionType
visible-change显示隐藏事件function
command命令事件,点击菜单项时触发function
clicksplitButton为true时,点击按钮触发function

Slots

NameDescription
default默认插槽
dropdown下拉菜单 SubComponents: PxDropdownItem

Expose

NameDescriptionType
open打开下拉菜单function
close关闭下拉菜单function

Props

NameDescriptionTypeDefault
command菜单项指令string | number-
label菜单项内容string | VNode-
disabled菜单项是否禁用booleanfalse
divided菜单项是否分割booleanfalse

Slots

NameDescription
default默认插槽,优先级高于props.label
本站访客数 人次 本站总访问量