vue3 封装 Dialog 弹窗组件,支持返回promise

vue3 封装 Dialog 弹窗组件,支持返回promise
在这里插入图片描述
Dialog .vue

<template>
  <div class="dialog-wrap">
    <div class="dialog-wrap-body">
      <div class="dialog-wrap-body-title">{{ title }}</div>
      <div class="dialog-wrap-body-content"> {{ content }} </div>
      <div class="dialog-wrap-body-footer">
        <div v-if="showCancel" class="cancel" @click="handleCancel" :style="{ color: cancelColor }">{{ cancelText }}
        </div>
        <div v-if="showConfirm" class="confirm" @click="handleSuccess" :style="{ color: confirmColor }">{{ confirmText
        }}
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
defineProps({
  title: String,
  content: String,
  showConfirm: Boolean,
  confirmText: String,
  confirmColor: String,
  showCancel: Boolean,
  cancelText: String,
  cancelColor: String,
  handleSuccess: Function,
  handleCancel: Function
})
</script>


<style lang="less" scoped>
.dialog-wrap {
  position: fixed !important;
  top: 0;
  height: 100vh;
  left: 0;
  width: 100vw;
  z-index: 3000;
  background-color: rgba(0, 0, 0, .4);
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;

  &-body {
    min-height: 400px;
    width: 80%;
    max-width: 750px;
    background: #fff;
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    color: #313131;

    &-title {
      min-height: 90px;
      padding: 0 20px;
      display: flex;
      align-items: center;
      font-size: 36px;
      font-weight: 600;
    }

    &-content {
      flex: 1;
      min-height: 140px;
      padding: 20px;
      font-size: 30px;
      line-height: 36px;
      box-sizing: border-box;
      display: flex;
      align-items: center;
    }

    &-footer {
      width: 100%;
      height: 90px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-top: 2px solid #e6e6e6;

      >div {
        flex: 1;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;
        font-size: 32px;
        font-weight: bold;

        &:last-child::before {
          content: ' ';
          display: inline-block;
          position: absolute;
          left: 0;
          height: 100%;
          width: 2px;
          background: #e6e6e6;
        }
      }
    }
  }

}
</style>


index.js

import { createApp } from 'vue'
import Dialog from './Dialog.vue'
export default {
  instance: null,
  parent: document.createElement('div'),
  clear () {
    if (this.instance !== null) {
      this.instance.unmount(this.parent)
      document.body.removeChild(this.parent)
      this.instance = null
    }
  },

  /**
   *  支持 返回 Promise
   * @param {*} options
   * @returns
   */
  showDialog (options) {
    if (this.instance !== null) this.clear()
    return new Promise(resolve => {
      if (!options) {
        if (isCallback(options.fail)) {
          options.fail()
        }
        throw new Error('调用错误')
      }
      const _this = this
      const defaultOptions = {
        title: '提示',
        content: '内容',
        showConfirm: true,
        confirmText: '确定',
        confirmColor: '#7127be',
        showCancel: true,
        cancelText: '取消',
        cancelColor: '#999999',
        handleSuccess: () => {
          if (isCallback(options.success)) {
            const res = { confirm: true }
            options.success(res)
            resolve(res)
          }
        },
        handleCancel: () => {
          if (isCallback(options.success)) {
            const res = { cancel: true }
            options.success(res)
            resolve(res)
          }
        }
      }
      function isCallback (callback) {
        _this.clear()
        if (callback && typeof callback === 'function') {
          return true
        }
        return false
      }
      Object.assign(defaultOptions, options)
      console.log(defaultOptions)
      this.instance = createApp(Dialog, defaultOptions)
      document.body.appendChild(this.parent)
      this.instance.mount(this.parent)
    })
  },  
}

//调用
import * as utils from './index.js'
utils.showDialog({title:"title",content:"content",success:({confirm,cancel})=>{console.log(confirm,cancel)}}) 
utils.showDialog({title:"title",content:"content"}).then(({confirm,cancel})=>{console.log(confirm,cancel)}) 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值