vue中使用el-dialog+Promise二次封装确认弹窗

小引

在很多时候,我们axios请求,或者采用第三方UI库进行二次封装的时候,经常会遇见下面这个问题,明明我想获取到的是一个Object的实例,可是抓取到的是一个Promise,我该怎么处理呢?

简单的写一个Promise用例

让我们先写一段简单的Promise的调用的不同方式的结果并输出:

javascript 复制代码
const success = true
function getTimeStamp() {
    return new Promise((resolve, reject) => {
        if (success) resolve(new Date())
        reject(new Error('异常'))
    })
}
const getPromiseValue1 = () => {
    const res = getTimeStamp()
    console.log('res', res)
}
const getPromiseValue2 = async () => {
    const res = await getTimeStamp()
    console.log('res', res)
}
const getPromiseValue3 = async () => {
    getTimeStamp().then(res=>{
        console.log('res', res)
    })
}
getPromiseValue1() // res Promise { 2023-11-02T04:56:27.386Z }
getPromiseValue2() // res 2023-11-02T04:56:27.393Z
getPromiseValue3() // res 2023-11-02T04:56:27.393Z

通常我们使用thenawait的方式从Promise的实例获取数据,但是因为then嵌套层级过深的时候,会掉进回调地狱,因此推荐使用await

vue中使用el-dialog+Promise二次封装确认弹窗

在父页面:

javascript 复制代码
const confirm = await this.$refs.modalRefName.confirm('提示','这是提示信息')
if(confirm === 'confirm') {
    // 点击确定
} else {
    // 点击取消
}

子组件

html 复制代码
<template>
  <div>
    <el-dialog v-model="visible" :show-close="false" width="450px" align-center>
      <div>
        <el-icon color="#FFC440" size="45px">
          <WarningFilled />
        </el-icon>
      </div>
      <div class="title">{{ title }}</div>
      <div class="sub-title">{{ subTitle }}</div>
      <div class="justify-evenly">
        <div class="btn-cancel" @click="cancelBtn">取消</div>
        <div class="btn-confirm" @click="confirmBtn">确定</div>
      </div>
    </el-dialog>
  </div>
</template>
	  
<script lang="ts">
export default { name: 'TipModal' }
</script>
	  
<script setup inherit-attrs="false" lang="ts" >
import { ref } from 'vue'
import { WarningFilled } from '@element-plus/icons-vue'

const visible = ref(false)
const title = ref('')
const subTitle = ref('')

const confirmBtn = ref();
const cancelBtn = ref();
const open = async () => {
  visible.value = true;
  return new Promise((resolve) => {
    confirmBtn.value = () => {
      visible.value = false;
      resolve('confirm');
    };
    cancelBtn.value = () => {
      visible.value = false;
      resolve('cancel');
    };
  });
};

defineExpose({
  async confirm(p_title = '提示', p_subTitle = '确认进行次操作?') {
    title.value = p_title
    subTitle.value = p_subTitle
    return await open();
  }
})
</script>
	  
<style scoped lang="scss">
.title {
  text-align: center;
  margin-top: 20px;
  font-size: 18px;
  font-weight: bolder;
  color: #334266;
}

.sub-title {
  text-align: center;
  margin-top: 6px;
  font-size: 16px;
  font-weight: 400;
  color: #334266;
}

.justify-evenly {
  display: flex;
  justify-content: space-evenly;
  margin-top: 38px;

  .btn-cancel {
    width: 110px;
    height: 32px;
    background: #fff;
    border-radius: 5px;
    opacity: 1;
    font-size: 14px;
    font-weight: 400;
    color: #8c93a4;
    border: 1px solid #d9d9d9;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }

  .btn-confirm {
    width: 110px;
    height: 32px;
    background: linear-gradient(270deg, #3392ff 0%, #8c9eff 100%);
    border-radius: 5px;
    opacity: 1;
    font-size: 14px;
    font-weight: 400;
    color: #ffffff;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }
}

:deep(.el-dialog) {
  border-radius: 10px;
  overflow: hidden;
}

:deep(.el-dialog__header) {
  margin-right: 0 !important;
  padding: 0 !important;
}

:deep(.el-dialog__body) {
  padding: 18px;
  text-align: center;
}
</style>
相关推荐
前端一小卒19 分钟前
一个看似“送分”的需求为何翻车?——前端状态机实战指南
前端·javascript·面试
syt_101322 分钟前
Object.defineProperty和Proxy实现拦截的区别
开发语言·前端·javascript
遝靑25 分钟前
Flutter 跨端开发进阶:可复用自定义组件封装与多端适配实战(移动端 + Web + 桌面端)
前端·flutter
cypking31 分钟前
Web前端移动端开发常见问题及解决方案(完整版)
前端
老前端的功夫36 分钟前
Vue 3 vs Vue 2 深度解析:从架构革新到开发体验全面升级
前端·vue.js·架构
栀秋6661 小时前
深入浅出链表操作:从Dummy节点到快慢指针的实战精要
前端·javascript·算法
狗哥哥1 小时前
Vue 3 动态菜单渲染优化实战:从白屏到“零延迟”体验
前端·vue.js
青青很轻_1 小时前
Vue自定义拖拽指令架构解析:从零到一实现元素自由拖拽
前端·javascript·vue.js
树下水月1 小时前
纯HTML 调用摄像头 获取拍照后的图片的base64
前端·javascript·html
蜗牛攻城狮1 小时前
Vue 中 `scoped` 样式的实现原理详解
前端·javascript·vue.js