Vue3从0到1组件开发-系统组件:Drawer抽屉

1,419 阅读1分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

简单说说抽屉

在开篇写的组件中,专门写过一篇基础组件Mask遮罩,这个组件在Web端属于是用的比较少的,所以一般在组件库中不会单独去写。

而我将它划分为了基础组件,作为其他组件的支撑组件。

本来是打算在下一部分的业务组件中去多用的,但是在选取系统组件时,发现一个也能用到的组件。就是这里要提到的Drawer抽屉组件要用到的。

抽屉组件也是常用来作为展示信息,在PC端来讲也是用的比较少的。

但是也总是部分地方需要用到。

先看看使用场景吧。

image.png

特意去找还真不好找,那就拿github的这个插件举例吧。

算是一个不那么标准的抽屉的应用。

浮于最顶级,包含标题,内容,自定义出现位置的展示块。

因为还是一个容器,所以相对要简单点。

还是从结构开始说。

<div v-transfer-dom :data-transfer="transfer">
  <transition name="fade">
    <div :class="['yx-drawer-mask', inner ? 'yx-drawer-inner' : '']" 
    :style="maskStyle" v-show="visible" v-if="mask" @click="handleMask"></div>
  </transition>
  <div :class="[
    'yx-drawer-wrap',
    wrapShow ? `yx-drawer-hidden` : '',
    className ? className : '',
    mask ? `yx-drawer-no-mask` : '',
    inner ? `yx-drawer-wrap-inner` : '',
    canMove ? `yx-drawer-wrap-dragging`: ''
  ]" 
  @click="handleWrapClick">
    <transition :name="'move-' + placement">
      <div :class="[
        'yx-drawer',
        `yx-drawer-${placement}`,
        !showHead ? 'yx-drawder-noheader' : '',
        inner ? 'yx-drawer-inner' : ''
      ]" :style="{width: `${width}px`}" v-show="visible">
        <div :class="[
          'yx-drawer-content',
          !mask ? 'yx-drawer-content-no-mask' :''
        ]" ref="content">
          <a class="ivu-drawer-close" v-if="closable" @click="close">
            <slot name="close">
              <yx-icon type="ios-close"></yx-icon>
            </slot>
          </a>
            <div class="yx-drawer-header" v-if="showHead"><slot name="header">
              <div class="yx-drawer-header-inner">{{ title }}</div>
              </slot>
            </div>
            <div class="yx-drawer-body" :style="styles"><slot></slot></div>
          </div>
          <div class="ivu-drawer-drag" :class="{ 'ivu-drawer-drag-left': placement === 'left' }" v-if="draggable" @mousedown="handleTriggerMousedown">
            <slot name="trigger">
              <div class="ivu-drawer-drag-move-trigger">
                <div class="ivu-drawer-drag-move-trigger-point">
                  <i></i><i></i><i></i><i></i><i></i>
                </div>
              </div>
            </slot>
          </div>
        </div>
      </transition>
  </div>
</div>

结构部分主要是header头部以及content内容部分两大块,样式部分进行微调即可。

逻辑部分

逻辑部分比较简单, 就是关闭事件的控制即可。

const close = () => {
  if (!props.beforeClose) {
    return handleClose();
  }

  const before = props.beforeClose();

  if (before && before.then) {
    before.then(() => {
      handleClose();
    });
  } else {
    handleClose();
  }
}
const handleClose = () => {
  this.visible = false;
  ctx.$emit('input', false);
  ctx.$emit('on-close');
}
const handleMask = () => {
  if (props.maskClosable && mask.value) {
    close();
  }
}

这一块也是比较自由的,以及内容区也可以去根据也无需求调整事件。