Vue 3.0 plugin showModal

356 阅读1分钟
/** index.vue **/

<template>
  <div class="ui-mask">
    <div class="ui-showModal plr32 bgfff">
      <div class="ui-showModal-title tc" v-if="title">
        <h5 class="fs36 font-semiBold font-weight">{{ title }}</h5>
      </div>
      <div class="ui-showModal-cont tc">
        <p class="fs28 lh44" v-html="content"></p>
      </div>
      <div class="ui-showModal-submit fs32 flex flex-h-between">
        <span class="tc" @click="cancelCallback">{{ cancelText }}</span>
        <strong class="tc font-semiBold" :style="{'background': confirmColor}" @click="successCallback">{{ confirmText }}</strong>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>

interface Props {
  title: string;
  content: string;
  cancelText: string;
  confirmText: string;
  confirmColor?: string;
  success(): void;
  cancel(): void;
}

const props = withDefaults(defineProps<Props>(), {
  title: '',
  content: '',
  cancelText: '取消',
  confirmText: '确定',
  confirmColor: '#16d2d7',
  success: () => {},
  cancel: () => {}
})


const successCallback = () => {
  props.success()
}
const cancelCallback = () => {
  props.cancel()
}


</script>

/** index.vue **/

/** index.ts **/

import { createVNode, render, App } from "vue"
import Modal from "./index.vue"

export default {
  install (app: App): void {
    let vm = null
    let isClick = true
    const container = document.createElement("div")
    app.config.globalProperties.$showModal = ({
      title,
      content,
      cancelText,
      confirmText,
      confirmColor,
      success,
      cancel
    }) => {
      if (!isClick) {
        return
      }
      if (!vm) {
        vm = createVNode(Modal as any, {
          title,
          content,
          cancelText,
          confirmText,
          confirmColor,
          success: () => {
            success && success()
            if (vm) {
              container.parentNode.removeChild(container)
              isClick = true
              vm = null
            }
          },
          cancel: () => {
            cancel && cancel()
            if (vm) {
              container.parentNode.removeChild(container)
              isClick = true
              vm = null
            }
          }
        })
      }
      isClick = false
      render(vm, container)
      document.body.appendChild(container)
    }
  }
}

/** index.ts **/

/** main.js **/
import { create, defineComponent } from 'vue'
import showModal from './showModal'
import App from "./App.vue"
const app = create(App)
app.use(showModal)

页面使用

import { getCurrentInstance, defineComponent } from 'vue'
export default defineComponent({

  setup() {
    const { proxy: { $showModal } } = getCurrentInstance()
    $showModal({
      content: "标题", 
      cancelText: "取消", 
      confirmText: "确定", 
      success: () => { }, 
      cancel: () => { }
    })
  }
})