跳到主要内容

drawer

drawer.ts

drawerProps

  • direction: values: ['ltr', 'rtl', 'ttb', 'btt']
  • size: default: '30%'
  • withHeader: default: true
  • modalFade: default: true
import { dialogEmits, dialogProps } from '@element-plus/components/dialog'

export const drawerProps = buildProps({
...dialogProps,
direction: {

drawerEmits

export const drawerEmits = dialogEmits

drawer.vue

setup

    const drawerRef = ref<HTMLElement>()
const focusStartRef = ref<HTMLElement>()
const ns = useNamespace('drawer')
const { t } = useLocale()

const isHorizontal = computed(
() => props.direction === 'rtl' || props.direction === 'ltr'
)
const drawerSize = computed(() => addUnit(props.size))

template

  • 在transition时候加了动画
    <transition
:name="ns.b('fade')"
  • 直接在overlay上设置了onClick处理
      <el-overlay
v-show="visible"
:mask="modal"
:overlay-class="modalClass"
:z-index="zIndex"
@click="onModalClick"
  • 直接在focus trap上设置focus-trap-el (dialog是在dialog-content内通过inject得到后设置的)
        <el-focus-trap
loop
:trapped="visible"
:focus-trap-el="drawerRef"
:focus-start-el="focusStartRef"
@release-requested="onCloseRequested"
  • 设置class,设置widthheight,对click事件stop propogation (所以前面overlay那里没用useSameTarget)
          <div
ref="drawerRef"
v-bind="$attrs"
:class="[ns.b(), direction, visible && 'open', customClass]"
:style="
isHorizontal ? 'width: ' + drawerSize : 'height: ' + drawerSize
"
role="dialog"
@click.stop
  • 设置slots: header, default, footer

packages\theme-chalk\src\drawer.scss

@include b(drawer) {
position: absolute;
box-sizing: border-box;
background-color: getCssVar('drawer', 'bg-color');
display: flex;
flex-direction: column;

&.ltr,
&.rtl {
height: 100%;
top: 0;
bottom: 0;
}

&.ltr {
left: 0;
}

&.rtl {
right: 0;
}