vue3 使用element-plus中的dialog像MessageBox一样可以进行方法调用

349 阅读1分钟

 前提

需要安装引入element-plus才可以进行调用

npm install element-plus --save

目的

1.简单场景下实现element-plus中的dialog像MessageBox一样可以进行方法调用

2.不需要维护visible变量

3.支持异步和同步加载弹框组件

4.支持Promise回调

代码实现

import { createVNode, createApp } from 'vue'

const createContainer = () => {
  const container = document.createElement('div')
  document.body.appendChild(container)
  return container
}

/**
 * 
 */
  
export const useModal = async ({ component, props }) => {

  if (component.__asyncLoader) {
    component = await component.__asyncLoader()
  }

  return new Promise((resolve, reject) => {
    const instance = createApp({
      render () {
        return createVNode(component, {
          ...props,
          onClosed: () => {
            instance.unmount()
            document.body.removeChild(instance._container)
          },
          resolve,
          reject,
        })
      }
    })

    const container = createContainer()
    instance.mount(container)
  })

}

代码调用

// 调用弹框的组件

<template>
  <div>
    <el-button type="primary"
               @click="handleBtn">Primary
    </el-button>
  </div>
</template>

<script setup>

import { defineAsyncComponent } from 'vue'
import { useModal } from './components'

const handleBtn = async () => {
  const res = await useModal({
    component: defineAsyncComponent(() => import('./comp.vue')),
    props: {
      a: 1,
      b: 2
    }
  })
}

</script>

// 弹框

<template>

  <el-dialog v-model="visibleRef"
             draggable>
    <el-button type="primary"
               @click="handleOk">OK</el-button>
    <el-button type="primary"
               @click="handleCancel">CANCEL</el-button>
  </el-dialog>

</template>

<script setup>
import { defineProps, ref } from 'vue'

let visibleRef = ref(true)

const props = defineProps(['resolve', 'reject', 'a', 'b'])

const handleOk = async () => {
  visibleRef.value = false
  props.resolve(true)
}

const handleCancel = async () => {
  visibleRef.value = false
  props.reject(false)
}

</script>