Skip to content

Drawer 抽屉

引入

js

js
<script type='module'>
  import "./node_modules/easy-component-ui/components/ea-drawer/index.js";
</script>

css

TIP

需要注意的是, 如果需要使用到带有图标的 属性/组件, 需要提前使用 link 标签引入 Font Awesome CSS 文件

html
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
/>

自定义样式

移步到 CSS Part

基本用法

呼出一个临时的侧边栏, 可以从多个方向呼出。可以在 ea-drawer 标签上添加 direction 属性来指定呼出方向。

从左往右开从右往左开从上往下开从下往上开Hi, there!
html
<div class="demo">
  <ea-button type="primary" id="openDrawerBtn--ltr">从左往右开</ea-button>
  <ea-button type="primary" id="openDrawerBtn--rtl">从右往左开</ea-button>
  <ea-button type="primary" id="openDrawerBtn--ttb">从上往下开</ea-button>
  <ea-button type="primary" id="openDrawerBtn--btt">从下往上开</ea-button>

  <ea-drawer id="drawer" title="I am the title" direction="ltr">
    <span>Hi, there!</span>
  </ea-drawer>
</div>
js
const CustomDrawer = {
  drawer: document.querySelector("#customDrawer"),
  openBtn: document.querySelector("#openCustomDrawerBtn"),
  cancelBtn: document.querySelector("#customCancelBtn"),
  confirmBtn: document.querySelector("#customConfirmBtn"),

  bindBeforeClose(actionType) {
    this.drawer.beforeClose = done => {
      const actionText = actionType === "cancel" ? "cancel" : "confirm";
      $confirm(`Are you sure you want to ${actionText}?`, "Warning", {
        confirmButtonText: "OK",
        cancelButtonText: "Cancel",
        type: "warning",
      })
        .then(action => {
          done();
        })
        .catch(action => {});
    };
  },

  init() {
    this.bindBeforeClose("cancel");

    this.openBtn.addEventListener("click", () => {
      this.drawer.visible = true;
    });

    this.cancelBtn.addEventListener("click", () => {
      this.bindBeforeClose("cancel");
      this.drawer.visible = false;
    });

    this.confirmBtn.addEventListener("click", () => {
      this.bindBeforeClose("confirm");
      this.drawer.visible = false;
    });

    this.drawer.addEventListener("closed", () => {
      this.bindBeforeClose("cancel");
    });
  },
};

CustomDrawer.init();

不添加 Title​

当你不需要标题的时候,你可以将它移除。

通过设置 with-header 属性为 false 来控制是否显示标题。 如果你的应用需要具备可访问性,请务必设置好 title。

openHi, there!
html
<div class="demo">
  <ea-button type="primary" id="noHeaderBtn">open</ea-button>
  <ea-drawer
    id="noHeaderDrawer"
    title="I am the title"
    direction="ltr"
    with-header="false"
  >
    <span>Hi, there!</span>
  </ea-drawer>
</div>
js
const noHeaderExample = {
  drawer: document.querySelector("#noHeaderDrawer"),
  openBtn: document.querySelector("#noHeaderBtn"),

  init() {
    this.openBtn.addEventListener("click", () => {
      this.drawer.visible = true;
    });
  },
};
noHeaderExample.init();

自定义内容

Drawer 可以在其内部嵌套各种丰富的操作

打开自定义内容的抽屉 Lilyiro Lord of the Wild Lunacrest Continent Thunderous Veins Daredevil She was once an elf lord, defending the border from goblin invaders. She was then a goblin warrior, protecting her clan from being slaughtered by elves. She has the unwavering courage to uphold justice in her heart and she is prepared to betray or be betrayed for the greater good. Despite her inner gentleness, Lilyiro, who has spilled so much blood on battlefields, is more straightforward than men.
CancelConfirm
html
<div class="demo">
  <ea-button type="primary" id="openCustomDrawerBtn"
    >打开自定义内容的抽屉</ea-button
  >
  <ea-drawer id="customDrawer" title="我是标题" direction="ltr">
    <ea-descriptions title="User Info">
      <ea-descriptions-item label="Username"> Lilyiro </ea-descriptions-item>
      <ea-descriptions-item label="Essence">
        Lord of the Wild
      </ea-descriptions-item>
      <ea-descriptions-item label="Place">
        Lunacrest Continent
      </ea-descriptions-item>
      <ea-descriptions-item label="Traits">
        <ea-tag size="small" type="warning" style="margin-right: 1rem">
          Thunderous Veins
        </ea-tag>
        <ea-tag size="small" type="info">Daredevil</ea-tag>
      </ea-descriptions-item>
      <ea-descriptions-item label="Description">
        She was once an elf lord, defending the border from goblin invaders. She
        was then a goblin warrior, protecting her clan from being slaughtered by
        elves. She has the unwavering courage to uphold justice in her heart and
        she is prepared to betray or be betrayed for the greater good. Despite
        her inner gentleness, Lilyiro, who has spilled so much blood on
        battlefields, is more straightforward than men.
      </ea-descriptions-item>
    </ea-descriptions>
    <footer slot="footer" style="text-align: right">
      <ea-button id="customCancelBtn" plain>Cancel</ea-button>
      <ea-button id="customConfirmBtn" type="primary">Confirm</ea-button>
    </footer>
  </ea-drawer>
</div>
js
const CustomDrawer = {
  drawer: document.querySelector("#customDrawer"),
  openBtn: document.querySelector("#openCustomDrawerBtn"),
  cancelBtn: document.querySelector("#customCancelBtn"),
  confirmBtn: document.querySelector("#customConfirmBtn"),

  bindBeforeClose(actionType) {
    this.drawer.beforeClose = done => {
      const actionText = actionType === "cancel" ? "cancel" : "confirm";
      $confirm(`Are you sure you want to ${actionText}?`, "Warning", {
        confirmButtonText: "OK",
        cancelButtonText: "Cancel",
        type: "warning",
      })
        .then(action => {
          done();
        })
        .catch(action => {});
    };
  },

  init() {
    this.bindBeforeClose("close");

    this.openBtn.addEventListener("click", () => {
      this.drawer.visible = true;
    });

    this.cancelBtn.addEventListener("click", () => {
      this.bindBeforeClose("cancel");
      this.drawer.visible = false;
    });

    this.confirmBtn.addEventListener("click", () => {
      this.bindBeforeClose("confirm");
      this.drawer.visible = false;
    });

    this.drawer.addEventListener("close", () => {
      this.bindBeforeClose("close");
    });
  },
};

CustomDrawer.init();

嵌套抽屉​

你可以像 Dialog 一样拥有多层嵌套的 Drawer

如果你需要在不同图层中多个抽屉,你必须设置 append-to-body 属性为 true

open
Click me!

_(:зゝ∠)_

html
<div class="demo">
  <ea-button type="primary" id="outerBtn">open</ea-button>
  <ea-drawer id="outerDrawer" title="I'm outer Drawer" size="50%">
    <div>
      <ea-button id="innerBtn">Click me!</ea-button>
      <ea-drawer
        id="innerDrawer"
        title="I'm inner Drawer"
        append-to-body="true"
      >
        <p>_(:зゝ∠)_</p>
      </ea-drawer>
    </div>
  </ea-drawer>
</div>
js
const nestingExample = {
  outerBtn: document.querySelector("#outerBtn"),
  innerBtn: document.querySelector("#innerBtn"),
  outerDrawer: document.querySelector("#outerDrawer"),
  innerDrawer: document.querySelector("#innerDrawer"),

  init() {
    this.outerBtn.addEventListener("click", () => {
      this.outerDrawer.visible = true;
    });

    this.innerBtn.addEventListener("click", () => {
      this.innerDrawer.visible = true;
    });

    this.innerDrawer.beforeClose = done => {
      $confirm("Are you confirm to close inner drawer?", "Warning", {
        confirmButtonText: "OK",
        cancelButtonText: "Cancel",
        type: "warning",
      })
        .then(action => {
          done();
        })
        .catch(action => {});
    };
  },
};
nestingExample.init();

Attributes

参数说明类型可选值默认值
title标题文本(同步到 header 中的 title)string-""
visible是否可见(受控属性,设置为 true/false)boolean-false
open兼容旧名,等同于 visible(文档中优先使用 visibleboolean-false
size抽屉尺寸,支持百分比或固定宽度/高度(根据 direction 决定是宽或高)string例如: "30%", "400px"30%
modal是否显示遮罩层boolean-true
direction抽屉方向stringltr(从左到右), rtl, ttb(从上到下), btt(从下到上)rtl
close-on-click-modal点击遮罩是否关闭(组件内部属性名)boolean-true
close-on-press-escape按下 Esc 是否关闭boolean-true
before-close是否启用 before-close 钩子(在关闭前触发事件,可通过 detail.done 控制)boolean-false
show-close是否显示右上角关闭图标(close icon)boolean-true
with-header是否显示头部(header)boolean-true
append-to-body是否挂载到 body(用于嵌套抽屉确保层级正确)boolean-false
append-to指定挂载宿主元素的选择器或元素(当需要自定义挂载点时使用)string例如: "#app" 或 "body"-
z-index自定义层级number--

CSS Part

用法可参考 MDN ::part()伪类

名称说明
container外层 overlay 容器,包含遮罩与抽屉 (对应模板中 .ea-overlay)
header抽屉头部(part="header"),包含 titleclose-icon
title标题容器(part="title"),对应 slot[name="title"] 的显示位置
close-icon关闭图标(part="close-icon"),可以自定义样式或隐藏
content主体内容区域(part="content"),对应默认 slot
footer底部区域(part="footer"),对应 slot[name="footer"]

Events

Drawer 是基于 Overlay 组件实现的,具体事件可参考 Overlay 组件

事件名说明回调参数 / detail
before-close关闭前触发(当 before-close 属性为 true 时,会在尝试关闭时触发){ done: Function } — 调用 done() 完成关闭

Slots

名称说明
(默认)抽屉主体内容,映射到模板中的默认 slot(part="content")
title标题内容,会显示在 header 的 title 区域(part="title")
footer底部插槽,显示在 footer 区域(part="footer")