Skip to content

Dropdown 下拉菜单

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

基础用法

通过组件 slot 来设置下拉触发的元素以及需要通过具名 slot 为 dropdown 来设置下拉菜单。

<script setup lang="ts">
import { type DropdownItemProps } from "eric-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="row">
    <div class="col">
      <div class="desc">通过 slot 传入 item</div>
      <er-dropdown>
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
        <template #dropdown>
          <er-dropdown-item command="1">Action 1</er-dropdown-item>
          <er-dropdown-item command="2" label="Action 2" />
          <er-dropdown-item command="3" disabled>Action 3</er-dropdown-item>
          <er-dropdown-item command="4" divided>Action 4</er-dropdown-item>
        </template>
      </er-dropdown>
    </div>
    <div class="col">
      <div class="desc">通过 props 传入 item</div>
      <er-dropdown :items="items">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
  </div>
</template>

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

触发方式

通过设置 trigger 属性来改变触发方式。

<script setup lang="ts">
import { type DropdownItemProps } from "eric-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="row">
    <div class="col">
      <div class="desc">hover to trigger</div>
      <er-dropdown :items="items">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
    <div class="col">
      <div class="desc">click to trigger</div>
      <er-dropdown :items="items" trigger="click">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
    <div class="col">
      <div class="desc">right click to trigger</div>
      <er-dropdown :items="items" trigger="contextmenu">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
  </div>
</template>

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

点击菜单隐藏

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

<script setup lang="ts">
import { type DropdownItemProps } from "eric-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="row">
    <div class="col">
      <div class="desc">hide-on-click="true"(default)</div>
      <er-dropdown :items="items">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
    <div class="col">
      <div class="desc">hide-on-click="false"</div>
      <er-dropdown :items="items" :hide-on-click="false">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
  </div>
</template>

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

指令事件

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

<script setup lang="ts">
import {
  type DropdownItemProps,
  type DropdownCommand,
  ErMessage,
} from "eric-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 },
];

function handleCommand(command: DropdownCommand) {
  ErMessage.info("click on item " + command);
}
</script>

<template>
  <er-dropdown :items="items" @command="handleCommand">
    <span class="dropdown-link">
      Dropdown List
      <er-icon icon="angle-down" />
    </span>
  </er-dropdown>
</template>

<style scoped>
.dropdown-link {
  display: flex;
  align-items: center;
  cursor: pointer;
  color: var(--er-color-primary);

  i {
    margin-left: 8px;
  }
}
</style>

下拉方法

可以手动使用 DropdownInstance.openDropdownInstance.close 以打开或关闭下拉菜单

<script setup lang="ts">
import type { DropdownItemProps, DropdownInstance } from "eric-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>
  <er-button @click="() => dropdownRef?.open()">open</er-button>
  <er-button @click="() => dropdownRef?.close()">close</er-button>
  <br />
  <er-dropdown ref="dropdownRef" :items="items">
    <span class="dropdown-link">
      Dropdown List
      <er-icon icon="angle-down" />
    </span>
  </er-dropdown>
</template>

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

禁用状态

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

<script setup lang="ts">
import { type DropdownItemProps } from "eric-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="row">
    <div class="col">
      <div class="desc">disabled</div>
      <er-dropdown :items="items" disabled>
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
    <div class="col">
      <div class="desc">undisabled</div>
      <er-dropdown :items="items">
        <span class="dropdown-link">
          Dropdown List
          <er-icon icon="angle-down" />
        </span>
      </er-dropdown>
    </div>
  </div>
</template>

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

触发对象

设置 split-button 属性来让触发下拉元素呈现为按钮组,左边是功能按钮,右边是触发下拉菜单的按钮。

<script setup lang="ts">
import { type DropdownItemProps, ErMessage } from "eric-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 },
];

function handleClick() {
  ErMessage.info("button click");
}
</script>

<template>
  <div class="row">
    <er-dropdown :items="items">
      <er-button type="primary">
        Dropdown List
        <er-icon icon="angle-down" style="margin-left: 8px" />
      </er-button>
    </er-dropdown>
    <er-dropdown
      :items="items"
      type="primary"
      @click="handleClick"
      split-button
    >
      Dropdown List
    </er-dropdown>
  </div>
</template>

<style scoped>
.row div {
  margin-right: 16px;
}
</style>

尺寸

通过设置 size 属性来改变下拉菜单和按钮的尺寸。

<script setup lang="ts">
import { type DropdownItemProps } from "eric-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="row">
    <er-dropdown :items="items" size="large" split-button>
      Large List
    </er-dropdown>
    <er-dropdown :items="items" split-button> Default List </er-dropdown>
    <er-dropdown :items="items" size="small" split-button>
      small List
    </er-dropdown>
  </div>
</template>

<style scoped>
.row div {
  margin-right: 16px;
}
</style>

Props

NameDescriptionTypeDefault
type菜单按钮类型同 Button 组件 的 type--
size菜单尺寸同 Button 组件 的 size--
split-button下拉触发元素呈现为按钮booleanfalse
disabled是否禁用booleanfalse
trigger触发方式'hover' | 'click' | 'contextmenu'hover
placement弹出位置'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' |...bottom
hideOnClick点击菜单项时是否隐藏下拉菜单booleantrue
show-timeout展开下拉菜单的延时,仅在 trigger 为 hover 时有效number150
hide-timeout收起下拉菜单的延时,仅在 trigger 为 hover 时有效number150

TIP

ps: 触发方式为 hover 时,如果出现弹出层不稳定的情况,可能是 hide-timeout 值过小,请增大该值。(默认值 150 经过验证较为稳定)

Events

NameDescriptionType
clicksplit-buttton 为 true 时,点击左侧按钮触发(event: MouseEvent) => void
visible-change下拉菜单显示或隐藏时触发(visible: boolean) => void
command点击菜单项时触发(command: string| number) => void

Slots

NameDescriptionSub Component
default默认插槽-
dropdown下拉菜单DropdownItem

Expose

NameDescriptionType
open打开下拉菜单() => void
close关闭下拉菜单() => void

Props

NameDescriptionTypeDefault
command菜单项指令string | number-
label菜单项文本string-
disabled禁用状态booleanfalse
divider添加分割线booleanfalse

Slots

NameDescription
default默认插槽, 优先级高于 props.label