Skip to content

Drawer 抽屉

引入

js

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

css

TIP

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

html
<link
  rel="stylesheet"
  href="./node_modules/easy-component-ui/components/ea-icon/index.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" before-close>
    <span>Hi, there!</span>
  </ea-drawer>
</div>
js
const Drawer = {
  drawer: document.querySelector("#drawer"),

  ltrBtn: document.querySelector("#openDrawerBtn--ltr"),
  rtlBtn: document.querySelector("#openDrawerBtn--rtl"),
  ttbBtn: document.querySelector("#openDrawerBtn--ttb"),
  bttBtn: document.querySelector("#openDrawerBtn--btt"),

  init() {
    this.ltrBtn.addEventListener("click", () => {
      this.drawer.direction = "ltr";
      this.drawer.visible = true;
    });

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

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

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

    this.drawer.addEventListener("before-close", e => {
      const { done } = e.detail;
      $confirm("Are you confirm to chose", "Warning", {
        confirmButtonText: "OK",
        cancelButtonText: "Cancel",
        type: "warning",
      })
        .then(action => {
          done();
        })
        .catch(action => {});
    });

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

Drawer.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 165cm 17岁 宿命背反雷电物理
CancelConfirm
html
<div class="demo">
  <ea-button type="primary" id="openCustomDrawerBtn"
    >打开自定义内容的抽屉</ea-button
  >

  <ea-drawer id="customDrawer" title="我是标题" direction="ltr" before-close>
    <ea-descriptions direction="vertical" border>
      <ea-descriptions-item label="用户名"> Lilyiro </ea-descriptions-item>
      <ea-descriptions-item label="身高"> 165cm </ea-descriptions-item>
      <ea-descriptions-item label="年龄"> 17岁 </ea-descriptions-item>
      <ea-descriptions-item label="称号">
        <ea-tag>宿命背反</ea-tag>
      </ea-descriptions-item>
      <ea-descriptions-item label="属性" span="1">
        <ea-tag type="warning" style="margin-right: 1rem">雷电</ea-tag>
        <ea-tag type="info">物理</ea-tag>
      </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"),

  init() {
    /**
     * @param {() => void || null} done
     */
    let done = null;

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

    this.cancelBtn.addEventListener("click", () => {
      this.drawer["before-close"] = false;
      this.drawer.visible = false;
    });

    this.confirmBtn.addEventListener("click", () => {
      this.drawer["before-close"] = true;

      this.drawer.visible = false;
    });

    this.drawer.addEventListener("before-close", e => {
      done = e.detail.done;

      $confirm("Are you confirm to chose", "Warning", {
        confirmButtonText: "OK",
        cancelButtonText: "Cancel",
        type: "warning",
      })
        .then(action => {
          done();
        })
        .catch(action => {});
    });
  },
};

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"
        before-close
      >
        <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.addEventListener("before-close", e => {
      const { done } = e.detail;
      $confirm("Are you confirm to chose", "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")