• 先封装一个管理dom元素的方法
// usePop.js
import { createApp } from "vue";

const createEl = () => {
  const el = document.createElement("div");
  el.setAttribute(
    "style",
    `
    position: fixed;
    top:0;
    left:0; 
    right: 0;
    bottom: 0;
    height: 100%;
    z-index: 2000;
    background-color: var(--el-overlay-color-lighter);
    overflow: auto;
    `
  );
  return el;
};

export const usePop = (container) => {
  const el = createEl();

  const createMyApp = () => createApp(container);
  let app;

  const show = () => {
    app = createMyApp();
    app.mount(el);
    document.body.appendChild(el);
  };

  const destroy = () => {
    if (app) app.unmount();
    document.body.removeChild(el);
  };

  const close = () => {
    destroy();
  };

  return {
    show,
    close,
  };
};
  • 随便写一个组件
// Welcome.vue
<script setup>

const props = defineProps(['title'])
const emit = defineEmits(['close'])
</script>

<template>
  <div>
    <h2>{{ title }}</h2>
    <el-button type="primary" @click="emit('close')">关闭</el-button>
  </div>
</template>

  • 封装一个组件的创建销毁的钩子函数
// useWelcome.js
import { h } from "vue";
import { usePop } from "./usePop";
import Welcome from "../components/Welcome.vue";

export const useWelcome = () => {
  const close = () => {
    welcomeInstance.close();
  };

  const show = () => {
    welcomeInstance.show();
  };

  const welcomeInstance = usePop(
    h(Welcome, {
      title: "欢迎",
      onClick: () => {
        console.log("xxx");
      },
      onClose: () => {
        close();
      },
    })
  );

  return {
    close,
    show,
  };
};
  • 引入组件方法使用
// App.vue
<script setup>
const { show, close } = useWelcome();
</script>

<template>
  <button @click="show">开</button>
  <button @click="close">关</button>
</template>

<style scoped></style>

最终效果如下

Q.E.D.


一个二次元web开发咸鱼