TS + vue3.2 + vite2 + element-plus 通用弹框组件封装

(注: 写时候有点急,所以没写啥注释,要用本代码但是不怎么理解的,可以下面评论,我基本上会看的哦~)

 这里基本el-dialog大部分功能都集成了,主要注意的是before-close回调事件的注意

props.beforeClose ? props.beforeClose(done) : done && done()

 这里是通过属性绑定的方式来回调beforeClose的,意思是你如果想使用此功能的话,就要在组件调用时,通过:before-close方式来, 常规的 确认按钮,通过 @confirm来调用,取消按钮不需要绑定时间,右上角关闭按钮,如果不想在这里做逻辑处理,只想关闭的话,直接调用@close,想做逻辑处理的话,就:before-close

// 组件调用

<Dialog
        :title="changePasswordDialog.title"
        :append-to-body="true"
        width="30%"
        top="15vh"
        v-model="changePasswordDialog.visible"
        showFooterBtn
        @confirm="handleDialogConfirm"
        @close="handleDialogClose"
      >
</Dialog>
<template>
  <el-dialog
    custom-class="dialo-modal"
    v-model="dialogVisible"
    :title="title"
    :width="width"
    :fullscreen="fullscreen"
    :lock-scroll="lockScroll"
    :close-on-click-modal="closeOnClickModal"
    :show-close="true"
    :top="top"
    :before-close="
      (done) => {
        handelCloseCallBack('close', done)
      }
    "
    @close="closeCallBack"
    destroy-on-close
  >
    <template v-if="isShowTitle" #title>
      <div class="dialog-head">
        <slot name="title"></slot>
      </div>
    </template>
    <div class="container scrollbar-bar">
      <slot></slot>
    </div>
    <template #footer v-if="showFooterBtn">
      <span class="dialog-footer">
        <slot name="footer">
          <el-button @click="handelCloseCallBack('cancel')">取 消</el-button>
          <el-button type="primary" @click="handelCloseCallBack('ok')">确 定</el-button>
        </slot>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts">
import { computed, defineComponent, ref, watch } from 'vue'
interface Props {
  modelValue: boolean
  width: string | number
  title: string
  top: string
  fullscreen: boolean
  isShowTitle: boolean
  lockScroll: boolean
  closeOnClickModal: boolean
  showFooterBtn: boolean
  beforeClose?: Function
}

export default defineComponent({
  name: 'Dialog',
  props: {
    modelValue: {
      type: Boolean,
      default: false
    },
    width: {
      type: String || Number,
      default: '50%'
    },
    title: {
      type: String,
      default: '提示'
    },
    top: {
      type: String,
      default: '15vh'
    },
    fullscreen: {
      type: Boolean,
      default: false
    },
    isShowTitle: {
      type: Boolean,
      default: false
    },
    lockScroll: {
      type: Boolean,
      default: true
    },
    closeOnClickModal: {
      type: Boolean,
      default: true
    },
    showFooterBtn: {
      type: Boolean,
      default: true
    },
    beforeClose: {
      type: Function
    }
  },
  emits: ['update:modelValue', 'before-close', 'close', 'handelClick', 'confirm'],
  setup(props: Props, { emit }) {
    const buttonType = ref<string>('')
    // 弹框显隐
    const dialogVisible = computed({
      get: () => props.modelValue,
      set: (val) => emit('update:modelValue', val)
    })

    // 关闭前回调
    const handelCloseCallBack = (type: string, done?: Function) => {
      buttonType.value = type
      console.log('type----', type)
      switch (type) {
        case 'close':
          //关闭
          props.beforeClose ? props.beforeClose(done) : done && done()
          // dialogVisible.value = false
          break
        case 'cancel':
          //取消
          dialogVisible.value = false
          break
        case 'ok':
          //确认
          emit('confirm', type)
          break
        default:
          emit('handelClick', type)
          break
      }
      // emit('before-close', type, done)
    }

    //关闭dialog后回调
    const closeCallBack = () => {
      // console.log('closeCallBack', buttonType.value)
      emit('close', buttonType.value)
    }

    return {
      dialogVisible,
      handelCloseCallBack,
      closeCallBack
    }
  }
})
</script>

<style lang="scss" scope>
$hd_height: 36px;
.dialo-modal {
  // min-width: 840px;
  .el-dialog__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: $hd_height;
    box-sizing: border-box;
    padding: 0 10px;
    background-color: #298db8;
    .el-dialog__title {
      font-size: 18px;
      color: #fff;
    }
    .el-dialog__headerbtn {
      position: inherit;
    }
    .el-dialog__close {
      width: 16px;
      height: 16px;
      border-radius: 50%;
      text-align: center;
      transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      transform-origin: 100% 50%;
      background-color: #bbcdff;
      color: #3b83ee;
      cursor: pointer;
      &:before {
        transform: scale(0.8);
        display: inline-block;
      }
      &:hover {
        opacity: 1;
        background-color: #d3dfff;
        color: #486ece;
      }
    }
  }
  .el-dialog__footer {
    text-align: center;
    button {
      width: 100px;
      height: 40px;
      margin-right: 8px;
      // border-radius: 18px;
    }
  }
  .container {
    width: 100%;
    //max-height: calc(100vh - 100px);
    //  max-height: 70vh;
    // overflow: hidden auto;
    box-sizing: border-box;
    .row-item {
      margin-bottom: 20px;
    }
    .col-title {
      margin: 18px 0 5px;
    }
  }
  .dialog-head {
    height: 35px;
    line-height: 35px;
    color: #fff;
    background-color: rgba(24, 175, 200, 1);
    padding: 0 16px 0 20px;
  }
}
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值