vue3 封装公共弹窗函数

前言:

博主封装了一个公共弹窗函数接收四个参数,(title:弹窗标题, ContentComponent:弹窗中显示的组件内容, opt:接收弹窗本身的属性和props, beforeSure:点击确定做的操作(请求后端接口))

封装的公共函数:

import { defineComponent, h, ref, getCurrentInstance } from "vue-demi";
import Vue from "vue";
import { isFunction, isUndefined, noop, isPlainObject } from "lodash";

const WRAPPED = "wrapped";

function generateDialogComponent(wrapped, opt, listeners = {}) {
  return defineComponent({
    setup() {
      const loading = ref(false);
      const vm = getCurrentInstance();
      const visible = opt.visible; // Ref<boolean>
      const closeable = opt.closeable; // Ref<boolean>
      const showCancelButton = isUndefined(opt.dialog.showCancelButton)
        ? true
        : opt.dialog.showCancelButton;
      const showSureBtn =
        isUndefined(opt.dialog.showSureBtn) &&
        isUndefined(opt.dialog.showSureButton)
          ? true
          : opt.dialog.showSureBtn || opt.dialog.showSureButton;
      const showFooter = isUndefined(opt.dialog.showFooter)
        ? true
        : opt.dialog.showFooter;
      const confirmButtonText = opt.dialog.confirmButtonText || "确定";
      const cancelButtonText = opt.dialog.cancelButtonText || "取消";

      return () => {
        const sure = listeners.sure || (() => Promise.resolve());
        const cancel = listeners.cancel || noop;
        const destroy = listeners.destroy || noop;
        // footer
        const sureBtn = h(
          "el-button",
          {
            props: {
              size: "mini",
              type: "primary",
              loading: loading.value,
            },
            on: {
              click: () => {
                loading.value = true;
                const wrappedVm = vm.proxy.$refs[WRAPPED];
                return sure(wrappedVm)
                  .then(() => {
                    visible.value = false;
                  })
                  .finally(() => (loading.value = false));
              },
            },
          },
          confirmButtonText
        );
        const cancelBtn = h(
          "el-button",
          {
            props: {
              size: "mini",
            },
            on: {
              click: () => {
                visible.value = false;
              },
            },
          },
          cancelButtonText
        );
        const footer = h(
          "div",
          {
            slot: "footer",
            style: {
              display: "flex",
              justifyContent: "space-between",
            },
          },
          [
            h("div", [opt.dialog?.leftFooter?.()]),
            h("div", [
              closeable.value && showCancelButton && cancelBtn,
              showSureBtn && sureBtn,
            ]),
          ]
        );
        return h(
          "el-dialog",
          {
            props: {
              closeOnClickModal: false,
              visible: visible.value,
              ...opt.dialog,
              closeOnClickModal: closeable.value,
              closeOnPressEscape: closeable.value,
              showClose: closeable.value,
            },
            on: {
              "update:visible": (val) => {
                visible.value = val;
              },
              closed: () => {
                cancel();
                destroy();
              },
            },
          },
          [
            h("div", { style: { padding: "20px" } }, [
              h(wrapped, {
                ref: WRAPPED,
                attrs: Object.assign({}, opt.props),
                on: {
                  close: sure, // 组件内部可以通过 emit('close') 来关闭弹窗
                },
              }),
            ]),
            showFooter && footer,
          ]
        );
      };
    },
  });
}

function openDialog(title, ContentComponent, opt, beforeSure) {
  const defaultOpt = {
    dialog: {},
    props: {},
  };
  // 参数格式化
  if (isUndefined(opt)) {
    opt = defaultOpt;
  }
  if (isFunction(opt)) {
    opt = defaultOpt;
    beforeSure = opt;
  }
  if (!isFunction(beforeSure)) {
    beforeSure = (vm) => vm.submit?.();
  }

  if (isPlainObject(opt)) {
    if (isUndefined(opt.props)) {
      opt = {
        ...opt,
        props: opt,
      };
    }
  }

  opt.dialog = opt.dialog || opt || {};
  opt.dialog.title = title;

  const mountComponent = ($vueconfig) => {
    const vm = new Vue($vueconfig);
    const anchor = document.createElement("div");
    document.body.appendChild(anchor);
    vm.$mount(anchor);
    return () => {
      vm.$destroy();
      document.body.removeChild(vm.$el);
    };
  };

  // 控制 dialog 显隐
  const visible = ref(false);
  const closeDialog = () => {
    visible.value = false;
  };

  // 控制是否可以关闭
  const closeable = ref(true);
  // 不可关闭弹窗
  const freeze = () => {
    closeable.value = false;
  };
  // 可关闭弹窗
  const unfreeze = () => {
    closeable.value = true;
  };

  const wait = new Promise((resolve, reject) => {
    let disposer = null;
    const destroy = () => isFunction(disposer) && disposer();
    const cancel = () => {
      reject(new Error("cancel"));
    };
    const sure = async (wrappedComp) => {
      const promise = await beforeSure(wrappedComp);
      resolve(promise);
    };
    disposer = mountComponent(
      generateDialogComponent(
        ContentComponent,
        { ...opt, visible, closeable },
        { sure, cancel, destroy }
      )
    );
    // 打开弹窗
    setTimeout(() => (visible.value = true), 20);
  });

  return {
    close: closeDialog,
    promise: wait,
    freeze,
    unfreeze,
  };
}

export function pickByDialog(...args) {
  const { promise } = openDialog(...args);
  return promise;
}

/**
 * 让 pickByDialog 静默失败, 并且提供一个手动关闭弹窗的函数
 * @Returns { close }
 */
export const openByDialog = (...args) => {
  const { close, freeze, unfreeze, promise } = openDialog(...args);
  promise.catch(() => {
    // no throw error
  });
  return {
    close,
    freeze,
    unfreeze,
  };
};

部分代码解释:

generateDialogComponent函数解释:

  1. generateDialogComponent函数定义了一个组件,并返回该组件。
  2. 在组件的setup函数中,首先定义了一些变量和常量,包括:
    • loading:一个用于表示加载状态的响应式变量(Ref)。
    • vm:当前组件实例的引用。
    • visible:一个响应式变量,表示对话框的可见性。
    • closeable:一个响应式变量,表示对话框是否可关闭。
    • showCancelButton:一个布尔值,表示是否显示取消按钮,默认为true
    • showSureBtn:一个布尔值,表示是否显示确定按钮,默认为true
    • showFooter:一个布尔值,表示是否显示底部内容,默认为true
    • confirmButtonText:确定按钮的文本,默认为"确定"。
    • cancelButtonText:取消按钮的文本,默认为"取消"。
  1. 返回一个函数,该函数使用Vue 3的Composition API语法,作为组件的渲染函数(render function)。
  2. 渲染函数返回一个el-dialog组件,该组件是一个基于Element UI库的对话框组件。
  3. el-dialog组件的属性包括:
    • closeOnClickModal:控制是否在点击模态框时关闭对话框,根据closeable的值进行设置。
    • visible:控制对话框的可见性,根据visible的值进行设置。
    • ...opt.dialog:将opt.dialog对象中的所有属性都作为el-dialog组件的属性。
    • closeOnClickModal:控制是否在点击模态框时关闭对话框,根据closeable的值进行设置。
    • closeOnPressEscape:控制是否在按下Esc键时关闭对话框,根据closeable的值进行设置。
    • showClose:控制是否显示关闭按钮,根据closeable的值进行设置。
  1. el-dialog组件的事件包括:
    • update:visible:当对话框的可见性发生变化时,更新visible的值。
    • closed:当对话框关闭时,触发canceldestroy函数。
  1. el-dialog组件的插槽包括:
    • 默认插槽:包含一个具有样式{ padding: "20px" }div元素,其中包含了wrapped组件。
    • showFootertrue时,底部插槽:包含一个具有样式{ display: "flex", justifyContent: "space-between" }div元素,其中包含了底部内容。
  1. 返回生成的组件。

openDialog的函数解释:

  1. openDialog函数接受四个参数:title(对话框标题),ContentComponent(对话框内容组件),opt(可选配置对象),和beforeSure(可选的确定按钮点击前的回调函数)。
  2. 定义了一个名为defaultOpt的默认配置对象,包含dialogprops两个属性。
  3. 对传入的optbeforeSure进行格式化处理:
    • 如果optundefined,则将其设置为defaultOpt的值。
    • 如果opt为函数,则将其设置为defaultOpt的值,并将beforeSure设置为该函数。
    • 如果beforeSure不是函数,则将其设置为一个默认函数,该函数会调用传入的组件实例的submit方法(如果存在)。
  1. opt进行进一步处理:
    • 如果opt是普通对象且没有props属性,则将opt的值复制给opt.props
  1. opt.dialog设置为optopt.dialog的值,并将title设置为opt.dialog.title
  2. 定义了一个名为mountComponent的函数,用于将组件挂载到DOM上,并返回一个销毁函数。
    • 在函数内部,创建了一个新的Vue实例,并将其挂载到一个新创建的div元素上。
    • 将该div元素添加到document.body中。
    • 返回一个函数,该函数在调用时会销毁Vue实例,并从document.body中移除该div元素。
  1. 创建了一个响应式的变量visible,用于控制对话框的显示和隐藏。
  2. 定义了一个closeDialog函数,用于关闭对话框。
  3. 创建了一个响应式的变量closeable,用于控制对话框是否可以关闭。
  4. 定义了freeze函数,将closeable设置为false,使对话框不可关闭。
  5. 定义了unfreeze函数,将closeable设置为true,使对话框可关闭。
  6. 创建了一个Promise对象wait,用于等待对话框的操作完成。
  7. wait的执行函数中,定义了一些内部函数和变量:

  • disposer:用于存储销毁函数的引用。
  • destroy函数:用于执行销毁函数。
  • cancel函数:用于拒绝Promise并抛出一个取消错误。
  • sure函数:在确定按钮点击时执行的回调函数,调用beforeSure函数并传入wrappedComp作为参数,并将返回的Promise解析为resolve的值。
  • disposer设置为调用mountComponent函数,并传入generateDialogComponent函数生成的对话框组件。
  • 使用setTimeout延迟20毫秒后,将visible设置为true,打开对话框。

  1. 返回一个对象,包含以下属性和方法:

  • close:关闭对话框的方法。
  • promise:返回等待对话框操作完成的Promise对象。
  • freeze:使对话框不可关闭的方法。
  • unfreeze:使对话框可关闭的方法。

使用方法例子如下

例子一

const { close } = openByDialog(
        "自定义列表",
        Setting2,
        {
          props: menuProps,
          dialog: {
            width: "980px",
            confirmButtonText: "保存",
            leftFooter: () =>
              h(
                "el-button",
                {
                  style: { color: "#2783fe" },
                  props: {
                    size: "mini",
                    type: "text",
                    loading: reseting.value,
                  },
                  on: {
                    click: () => doReset(),
                  },
                },
                "恢复系统默认设置"
              ),
          },
        },
        async (componentWrapper) => {
          const updatedColumns = await componentWrapper?.updateColumnSetting();
          this.emitChangeColumns2(updatedColumns);
        }
      );

例子二

//组件弹窗测试
      async doImportLog() {
        const [cancel, blob] = await to(
          pickByDialog(
            "弹窗导出测试",
            getLogComp(this), //这个是组件
            {
              dialog: { width: "35%" },
              // props: { value: this.value },
              // on: {
              //   input: (val) => {
              //     this.value = val
              //   },
              // },
            },
            async (vm) => {
              const [changeDateBt, changeDateEt] = vm.date;
              console.log("changeDateBt", changeDateBt);
              console.log("changeDateEt", changeDateEt);
            }
          )
        );
        if (cancel) {
          this.$message.info(this.$tof("cancel"));
          return;
        }
        const curDate = dayjs().format("YYYYMMDD");
        console.log("curDate", curDate);
        saveAs(blob.data, this.$tof("file_name", { curDate }));
      },


  function getLogComp(vm) {
    return {
      data() {
        return {
          date: [],
        };
      },
      render(h) {
        return h("el-row", { style: { margin: "100px 50px" } }, [
          h(
            "el-col",
            { style: { lineHeight: "36px" }, attrs: { span: 8 } },
            "导出范围时间"
          ),
          h("el-col", { attrs: { span: 16 } }, [
            h("el-date-picker", {
              attrs: {
                type: "daterange",
                rangeSeparator: "-",
                startPlaceholder: "开始日期",
                endPlaceholder: "结束日期",
                value: this.date,
                valueFormat: "yyyy-MM-dd",
              },
              style: { width: "auto !important" },
              on: {
                input: (val) => {
                  this.date = val;
                },
              },
            }),
          ]),
        ]);
      },
    };
  }

例子三

//组件弹窗测试222
      async doAdd() {
        const [cancel] = await to(
          pickByDialog(
            "新增客户",
            GroupCreate, //组件
            {
              dialog: {
                width: "80%",
                confirmButtonText: "保存",
                leftFooter: () =>
                  h(
                    "el-button",
                    {
                      style: { color: "#2783fe" },
                      props: {
                        size: "mini",
                        type: "text",
                        loading: false,
                      },
                      on: {
                        click: () => doReset(),
                      },
                    },
                    "恢复系统默认设置"
                  ),
              },
              props: {},
            },
            async (vm) => {
              console.log("测试点击确定", vm);
            }
          )
        );
        if (cancel) {
          this.$message.info("已取消");
          return;
        }
        function doReset() {
          console.log("测试左边操作");
        }
      },


    GroupCreate组件:

    
    <template>
  <div>
    <CollapsePanel :show-header="true">
      <template #panel-button>
        <el-button
          size="small"
          type="primary"
          :loading="loading"
          @click="doInquiry"
        >
          搜索
        </el-button>
      </template>
      <template #panel-main>
        <el-form
          ref="filterForm"
          :inline="true"
          :model="schemaModel"
          :max-height="200"
          class="list-schema-form"
          label-position="top"
        >
          <el-row
            v-for="(row, index) in schemaList"
            :key="index"
            v-bind="layout"
          >
            <el-col
              v-for="{ rules, label, prop, component, ...attrs } in row"
              :key="prop"
              :span="12"
            >
              <el-form-item v-if="prop" v-bind="{ label, rules, prop }">
                {{ component }}
                <component
                  :is="`el-${component}`"
                  v-model="schemaModel[prop]"
                  :placeholder="component + '_placeholder'"
                  v-bind="attrs"
                >
                  <el-option
                    v-for="ops in schemaOptions[prop]"
                    :key="ops.value"
                    v-bind="ops"
                  />
                </component>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </template>
    </CollapsePanel>

    <CollapsePanel :auto-height="true">
      <template #panel-main>
        <el-table
          ref="tableRef"
          v-loading="loading"
          :data="list"
          border
          stripe
          max-height="550"
        >
          <el-table-column type="selection" fixed="left" width="40" />
          <el-table-column
            type="index"
            width="60"
            fixed="left"
            :label="'序号'"
          />
          <el-table-column
            v-for="{ field, render, ...attrs } in columns"
            :key="field"
            v-bind="attrs"
          >
            <template #default="scope">
              <field-render :render="render" :scope="scope" :field="field" />
            </template>
          </el-table-column>
        </el-table>
        <div class="table-pagination">
          <pagination
            :limit="pageSize"
            :page="pageNum"
            :total="totalPages"
            @pagination="(pageNum = $event.page) && (pageSize = $event.limit)"
          />
        </div>
      </template>
    </CollapsePanel>
  </div>
</template>

<script>
  // import { customerinfoFindCustByCustNameOrCustCodeToCommodity } from '@/api/commodity/price'

  import to from "await-to-js";
  import { snakeCase } from "lodash";

  export default {
    name: "GroupCreate",
    components: {
      FieldRender: {
        functional: true,
        props: {
          scope: {
            type: Object,
            default: () => ({}),
          },
          render: Function,
          field: String,
        },
        render: (h, { props }) => {
          const { render, scope, field } = props;
          return render
            ? render(h, { ...scope, field })
            : h("span", null, scope.row[field]);
        },
      },
    },
    data(vm) {
      return {
        ...getSchemaList(vm),
        list: [],
        columns: getColumList(vm),
        pageNum: 1,
        pageSize: 10,
        totalPages: 0,
        loading: false,
        layout: {
          gutter: 60,
          justify: "start",
        },
      };
    },
    watch: {
      pageNum: {
        handler() {
          this.doInquiry();
        },
      },
      pageSize: {
        handler() {
          this.doInquiry();
        },
      },
    },
    async created() {
      // const options = await this.$ops({});
      // Object.assign(this.schemaOptions, options);

      this.doInquiry();
    },
    methods: {
      async doInquiry() {
        console.log("测试");
        // this.loading = true
        // const [err, data] = await to(
        //   customerinfoFindCustByCustNameOrCustCodeToCommodity(
        //     Object.assign(this.schemaModel, {
        //       page: this.pageNum - 1,
        //       size: this.pageSize,
        //     })
        //   )
        // ).finally(() => (this.loading = false))
        // if (err) {
        //   return
        // }

        // const { content, totalElements = 5 } = data
        // this.totalPages = +totalElements
        // this.list = content.map((i) => ({
        //   custCode: i.customerCode,
        //   custName: i.customerName,
        // }))
      },
      doReset() {
        this.schemaModel = {};
      },
      doDelete() {},
      doAdd() {},
      async doSave() {
        const [err] = await to(this.$refs["filterForm"].validate());
        if (err) {
          return;
        }
      },
      doBack() {
        this.$store.dispatch("tabsBar/delVisitedRoute", this.$route.fullPath);
        this.$router.back();
      },
    },
  };

  function getColumList(vm) {
    const COLUM_FIELDS = ["custCode", "custName"];
    const FORM_FIELDS_NAME = {
      custName: "客户名称",
      custCode: "客户编码",
    };

    const colProperties = {};
    return COLUM_FIELDS.map((prop) =>
      Object.assign(
        { prop, label: FORM_FIELDS_NAME[prop], field: prop },
        colProperties[prop] || {
          sortable: true,
        }
      )
    );
  }

  function getSchemaList(vm) {
    const FORM_FIELDS = ["custCode", "custName"];
    const FORM_FIELDS_NAME = {
      custName: "客户名称",
      custCode: "客户编码",
    };
    let properties = {
      custCode: {},
      custName: {},
    };
    const array = FORM_FIELDS.map((prop) => {
      const label = FORM_FIELDS_NAME[prop];
      const attrs = properties[prop];

      return {
        prop,
        label,
        clearable: true,
        filterable: true,
        component: "input",
        ...attrs,
      };
    });

    const schemaList = [array];
    return {
      schemaList,
      schemaModel: { custStatus: ["20"], custCode: "", custNameList: [] },
      schemaOptions: { status: [] },
    };
  }
</script>

<style lang="scss" scoped>
  ::v-deep .el-button--text {
    color: #409eff;
    font-size: 13px;
  }
  .total-number {
    color: #f55448;
  }
</style>

例子四

 async doAdd2() {
        openByDialog(
          "测试表单",
          FormTest,
          {
            props: {
              isShowCol: true,
            },
          },
          async (componentWrapper) => {
            await componentWrapper?.$children[0].validate();
            console.log("componentWrapper的数据", componentWrapper);
            componentWrapper.ruleForm.date1 = dayjs(
              componentWrapper.ruleForm.date1
            ).format("YYYYMMDD");

            let payload = componentWrapper.ruleForm;

            return await this.fetchData(payload);
          }
        );
      },


FormTest组件
<template>
  <el-form
    :model="ruleForm"
    :rules="rules"
    ref="ruleFormRef"
    label-width="100px"
    class="demo-ruleForm"
  >
    <el-form-item label="活动名称" prop="name">
      <el-input v-model="ruleForm.name"></el-input>
    </el-form-item>
    <el-form-item label="活动区域" prop="region">
      <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
        <el-option label="区域一" value="shanghai"></el-option>
        <el-option label="区域二" value="beijing"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="活动时间" required>
      <el-col :span="11">
        <el-form-item prop="date1">
          <el-date-picker
            type="date"
            placeholder="选择日期"
            v-model="ruleForm.date1"
            style="width: 100%"
          ></el-date-picker>
        </el-form-item>
      </el-col>
      <el-col class="line" :span="2">-</el-col>
      <el-col :span="11">
        <el-form-item prop="date2">
          <el-time-picker
            placeholder="选择时间"
            v-model="ruleForm.date2"
            style="width: 100%"
          ></el-time-picker>
        </el-form-item>
      </el-col>
    </el-form-item>
    <el-form-item label="即时配送" prop="delivery">
      <el-switch v-model="ruleForm.delivery"></el-switch>
    </el-form-item>
    <!-- <el-form-item label="活动性质" prop="type">
        <el-checkbox-group v-model="ruleForm.type">
          <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
          <el-checkbox label="地推活动" name="type"></el-checkbox>
          <el-checkbox label="线下主题活动" name="type"></el-checkbox>
          <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
        </el-checkbox-group>
      </el-form-item> -->
    <el-form-item label="特殊资源" prop="resource">
      <el-radio-group v-model="ruleForm.resource">
        <el-radio label="线上品牌商赞助"></el-radio>
        <el-radio label="线下场地免费"></el-radio>
      </el-radio-group>
    </el-form-item>
    <el-form-item label="活动形式" prop="desc">
      <el-input type="textarea" v-model="ruleForm.desc"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm(ruleFormRef)">
        立即创建
      </el-button>
    </el-form-item>
  </el-form>
</template>

<script>
  import { defineComponent, ref } from "vue-demi";
  export default defineComponent({
    name: "ruleFormTest",
    props: {
      isShowCol: {
        type: Boolean,
        default: false,
      },
    },
    setup(props) {
      const ruleFormRef = ref();
      let ruleForm = ref({
        name: "",
        region: "",
        date1: "",
        date2: "",
        delivery: props.isShowCol,
        type: [],
        resource: "",
        desc: "",
      });
      let rules = ref({
        name: [
          { required: true, message: "请输入活动名称", trigger: "blur" },
          { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
        ],
        region: [
          { required: true, message: "请选择活动区域", trigger: "change" },
        ],
        date1: [
          {
            type: "date",
            required: true,
            message: "请选择日期",
            trigger: "change",
          },
        ],
        date2: [
          {
            type: "date",
            required: true,
            message: "请选择时间",
            trigger: "change",
          },
        ],
        type: [
          {
            type: "array",
            required: true,
            message: "请至少选择一个活动性质",
            trigger: "change",
          },
        ],
        resource: [
          { required: true, message: "请选择活动资源", trigger: "change" },
        ],
        desc: [{ required: true, message: "请填写活动形式", trigger: "blur" }],
      });

      const submitForm = async (formEl) => {
        console.log("formEl", formEl);
        if (!formEl) return;
        await formEl.validate((valid, fields) => {
          if (valid) {
            console.log("submit!");
          } else {
            console.log("error submit!", fields);
          }
        });
      };
      const resetForm = (formName) => {};
      // expose({ submitForm });
      return {
        ruleForm,
        rules,
        ruleFormRef,
        submitForm,
        resetForm,
      };
    },
  });
</script>

模拟一个异步返回

      fetchData(params) {
        return new Promise((resolve, reject) => {
          // 模拟异步请求
          setTimeout(() => {
            const data = { name: "John", age: 30, ...params };
            // 模拟请求成功
            resolve(data);
            // this.$message.error("请求接口失败");
            // 模拟请求失败
            // reject('请求失败');
          }, 1000);
        });
      },

填写完必填项发起后端请求,拿到数据

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3封装全局弹窗组件的步骤如下: 1. 创建一个Vue实例,作为全局弹窗组件的容器。可以使用`createApp`方法创建Vue实例,并将其挂载到一个DOM元素上。 2. 在全局弹窗组件上定义必要的属性和方法。比如,可以定义一个`visible`属性控制弹窗的显示与隐藏,一个`title`属性用于显示弹窗的标题,一个`content`属性用于显示弹窗的内容等。 3. 在全局弹窗组件内部实现弹窗的样式和交互逻辑。可以使用Vue的模板语法和样式定义实现弹窗的外观和样式效果,并通过Vue的响应式特性,实现弹窗的交互逻辑,比如点击关闭按钮时隐藏弹窗。 4. 添加全局方法,在Vue实例的原型上添加一个方法,用于在任意组件中调用弹窗组件。可以使用`app.config.globalProperties`来添加全局方法,以便在任何地方都可以访问到该方法。 5. 在组件中使用全局弹窗组件。在需要显示弹窗的组件中,通过调用全局方法来调用弹窗组件。可以通过传递参数的方式,动态设置弹窗的内容和样式。 6. 在全局弹窗组件的内部实现弹窗的生命周期钩子函数,比如`mounted`函数用于在弹窗组件被挂载到DOM后执行相应的逻辑。 通过以上步骤,就可以封装一个可在任何组件中使用的全局弹窗组件。在使用过程中,只需要调用全局方法,传入相应的参数,即可显示自定义的弹窗内容和样式,提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值