ant-design封装抽屉组件

DrawerBox.vue

<template>
  <transition name="slide-out" mode="out-in">
    <div class="setbox flex flex-col" v-if="visible" ref="slide_box_content">
      <div class="title flex flex-between">
        <div style="font-weight: bolder">{{ title }}</div>
        <CloseOutlined class="cursorPointer" @click="emit('update:visible')" style="color: #9a9fa8" />
      </div>
      <div class="pt-20 pr-20 pl-20 pb-0 box-conetent" :style="{ width: props.isAutoWidth ? 'auto' : '1200px' }">
        <slot></slot>
      </div>
      <div class="footer">
        <slot name="footer"></slot>
      </div>
    </div>
  </transition>
</template>

<script setup>
import { CloseOutlined } from '@ant-design/icons-vue'
import { ref, watch, onBeforeUnmount, provide } from 'vue'
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '标题'
  },
  isAutoWidth: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['update:visible', 'closeModal'])

provide('stickyConfig', { offsetHeader: -20 })

const slide_box_content = ref(null)
const clickClose = event => {
  if (
    event.target !== slide_box_content.value &&
    !slide_box_content.value?.contains(event.target) &&
    !['text', 'circle'].includes(event.target.nodeName) &&
    !['ant-modal'].includes(event.target.parentElement.parentElement.className) &&
    !['ant-modal', 'ant-tabs', 'ant-col', 'ant-popover-open', 'a-color', 'ant-modal-wrap ant-modal-centered'].includes(
      event.target.className
    ) &&
    !['ant-table-cell-content', 'ant-table-cell'].includes(event.target.parentElement.className) &&
    !hasParentWithClass(event.target, 'ant-modal-wrap')
  ) {
    handleCancel()
  }
}

const hasParentWithClass = (element, className) => {
  while (element.parentElement) {
    if (element.parentElement.classList.contains(className)) {
      return true // 找到具有指定类名的父元素
    }
    element = element.parentElement // 继续向上查找
  }
  return false // 没有找到具有指定类名的父元素
}

const handleCancel = () => {
  emit('update:visible')
  emit('closeModal')
  document.body.removeEventListener('click', clickClose)
}

watch(
  () => props.visible,
  v => {
    if (v) {
      setTimeout(() => {
        document.body.addEventListener('click', clickClose)
      }, 0)
    }
  }
)

onBeforeUnmount(() => {
  document.body.removeEventListener('click', clickClose)
})
</script>

<style lang="less" scoped>
@import '@/assets/css/constant.less';
.setbox {
  position: fixed;
  z-index: 9999;
  top: @NavHeight;
  bottom: 0px;
  height: 100%;
  background: #fff;
  box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.1);
  right: 0;
  padding-bottom: 88px;
  max-width: 1200px;
}

.slide-out-enter-from {
  transition: all 0.3s;
  transform: translateX(100%);
}

/* slide-out过渡 */
.slide-out-enter-active,
.slide-out-leave-active {
  transition: all 0.3s;
  /* 控制过渡持续时间 */
}

.slide-out-enter,
.slide-out-leave-to {
  transform: translateX(100%);
}

.title {
  line-height: 56px;
  padding: 0px 24px;
  color: #333;
  font-size: 16px;
  font-weight: bold;
  background: #f8f9fb;
  width: 100%;
}
.box-conetent {
  overflow-y: auto;
}
.footer {
  display: flex;
  justify-content: center;
  width: 100%;
  margin-top: 20px;
}
</style>

其他文件中使用

<template>
  <DrawerBox v-model:visible="state.visible" title="修改密码" isAutoWidth>
    <div>
      <a-form labelAlign="left" :model="Pwdform" ref="resetPsdRef" :rules="Pwdrules" layout="vertical">
        <a-form-item label="原密码" name="oldPwd" class="label_sty">
          <a-input-password v-model:value="Pwdform.oldPwd" placeholder="请输入原密码" class="input_sty" />
        </a-form-item>
        <a-form-item label="设置新密码" name="pwd" class="label_sty">
          <a-input-password v-model:value="Pwdform.pwd" placeholder="密码为8~30位的英文、数字、字符组合" class="input_sty" />
        </a-form-item>
        <a-form-item label="再次输入密码" name="Newpwd" class="label_sty">
          <a-input-password v-model:value="Pwdform.Newpwd" placeholder="请再次输入密码" class="input_sty" />
        </a-form-item>
      </a-form>
    </div>
    <template #footer>
      <a-button type="primary" style="margin-right: 10px" class="confirm_ok long-btn" @click="confirmOk">确定</a-button>
      <a-button @click="onClose" class="confirm_close long-btn">取消</a-button>
    </template>
  </DrawerBox>
</template>
<script setup>
import DrawerBox from '@/components/DrawerBox/index.vue'

const showDrawer = () => {
  state.visible = true
}
</script>

效果图
在这里插入图片描述

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值