弹窗工具类

封装初意是为了实现脱离html标签来使用的简单的弹窗

  • 完全动态创建和销毁

  • 不依赖模板文件

  • 支持通过props传递数据和回调

  • 适合作为全局弹窗组件使用

组件定义

const DialogComponent = Vue.extend({
  props: ["title", "content", "onClose"],
  methods: { /* 关闭逻辑 */ },
  render(h) { /* 虚拟DOM结构 */ }
})
  • 核心机制:通过 Vue.extend + render 函数实现声明式弹窗模板

  • 样式方案:内联样式对象集中管理,统一采用JS对象风格写法

  • 交互响应:同时支持遮罩层点击关闭和按钮点击关闭

服务化封装层

export function showDialog(options) {
  const instance = new DialogComponent(...)
  document.body.appendChild(instance.$el)
  return instance
}
  • 动态挂载:按需创建新实例并挂载到body末尾

  • 服务式调用:导出函数实现API式调用 (showDialog({ title:'Hi' }))


import Vue from "vue";

const DialogComponent = Vue.extend({
  props: ["title", "content", "onClose"], // 已添加onClose回调prop
  methods: {
    close() {
      if (typeof this.onClose === "function") {
        this.onClose(); // 触发父组件传递的回调函数
      }
      this.$destroy();
      this.$el.parentElement.removeChild(this.$el);
    },
  },
  render(h) {
    const styles = {
      mask: {
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: "rgba(0,0,0,0.5)",
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        zIndex: 999,
      },
      dialog: {
        backgroundColor: "white",
        borderRadius: "4px",
        padding: "20px",
        minWidth: "300px",
        boxShadow: "0 2px 12px 0 rgba(0,0,0,0.1)",
      },
      header: {
        fontSize: "18px",
        fontWeight: "bold",
        marginBottom: "10px",
      },
      content: {
        marginBottom: "15px",
      },
      footer: {
        textAlign: "right",
      },
      closeBtn: {
        padding: "6px 12px",
        backgroundColor: "#409eff",
        color: "white",
        border: "none",
        borderRadius: "3px",
        cursor: "pointer",
      },
    };

    return h("div", {
        style: styles.mask,
        on: {
          click: e => e.target === this.$el && this.close(),
        },
      },[
        h("div", { style: styles.dialog }, [
          h("div", { style: styles.header }, this.title),
          h("div", { style: styles.content }, this.content),
          h("div", { style: styles.footer }, [
            h(
              "button",
              {
                style: styles.closeBtn,
                on: { click: this.close },
              },
              "关闭"
            ),
          ]),
        ]),
      ]
    );
  },
});

export function showDialog(options) {
  const instance = new DialogComponent({
    propsData: options,
  }).$mount();

  document.body.appendChild(instance.$el);
  return instance;
}


弹窗工具类
https://halo.jiangling.site/archives/dialog-util
作者
你的降灵
发布于
2025年07月13日
许可协议