Modal

模态框是一种悬浮悬浮于主窗口的用来现实额外内容的对话框,允许自定义对话内容,几乎可以内嵌其他任何组件和元素。

<div>
  <nly-button variant="primary" v-nly-modal.no-close-on-esc.modal-1
    >点击弹出Modal</nly-button
  >

  <nly-modal id="modal-1" title="NlyAdminlteVue">
    <p class="my-4">Hello NlyAdminlteVue</p>
  </nly-modal>
</div>

<!-- 总览.name -->
<!-- nly-modal.vue -->

总览

在默认下, nly-modal 在底部有 取消 和 确定的按钮,用来进行确认操作和关闭操作。 可以通过 nly-modal 的专门 prop 来对这些按钮进行设置。同时也可以用对应的 modal-okmodal-cancel 插槽来嵌入其他元素和组件来替换按钮。

nly-modal 在默认下是可以使用键盘上的 ESC 按键来关闭的,也可以通过点击 nly-modal 的罩层来关闭,还可以通过点击 nly-modal 右上角的 X 按钮来关闭。 这些关闭行为都是默认的。您可以通过设置 prop no-close-on-esc , no-close-on-backdrop , hide-header-close 来禁止对应的行为, 指令 nly-modal 无效。

可以设置 modal-title , modal-header , modal-footer 插槽来设置元素和组件嵌入 modal 的标题,头部和底部

nly-modal 懒加载模式不会渲染 dom 元素,只有在点击触发显示的时候才会渲染,您可以设置 static 来实现初始渲染

注意

使用 modal-footer 插槽时,默认的 确定 和 取消 按钮不会显示,需要您自己设置。如果您使用 modal-header 插槽,默认的页眉关闭按钮 X 也不会显示,也无法使用 modal-title 插槽。

切换 nly-modal 的隐藏和展示状态

您可以通过以下方法来关闭和显示模态框

使用 v-nly-modal 指令

v-nly-modal 可以快速控制 nly-modal 显示和隐藏

<div>
  <!-- 使用 modifiers -->
  <nly-button variant="primary" v-nly-modal.my-modal>点击显示</nly-button>

  <!-- 使用 value -->
  <nly-button variant="primary" v-nly-modal="'my-modal'">点击显示</nly-button>

  <nly-modal id="my-modal">Hello NlyAdminlteVue</nly-modal>
</div>

<!-- v-nly-modal 指令显示隐藏.name -->
<!-- v-nly-modal.vue -->

使用 $nlyaModal

如果是 import "NlyAdminlteVue" ... 或者注册为 插件的时候( ModalPlugin ), NlyAdminlteVue 会给每个组件注入一个 $nlyaModal 对象,来控制 nly-modal 的展示和隐藏

方法 描述
this.$nlyaModal.show(id) 显示 模态框, id 为模态框的 id
this.$nlyaModal.hide(id) 隐藏 模态框, id 为模态框的 id
<div>
  <nly-button
    variant="primary"
    id="show-btn"
    @click="$nlyaModal.show('nly-modal-example')"
    >显示</nly-button
  >

  <nly-modal id="nly-modal-example" hide-footer>
    <template v-slot:modal-title> 使用 <code>$nlyaModal</code> 方法 </template>
    <div class="d-block text-center">
      <h3>Hello NlyAdminlteVue!</h3>
    </div>
    <nly-button
      variant="primary"
      class="mt-3"
      block
      @click="$nlyaModal.hide('nly-modal-example')"
      >关闭</nly-button
    >
  </nly-modal>
</div>

<!-- $nlyaModal 显示隐藏.name -->
<!-- nly-modal-hide-show.vue -->

this.$nlyaModal 同样可以使用于 显示 模态消息框

使用 show() , hide() , toggle()

show() , hide() , toggle() 3 个方法是 nly-modal 暴露出来的方法, 可以通过 ref 来调用

<template>
  <div>
    <nly-button variant="primary" id="show-btn" @click="showModal"
      >show</nly-button
    >
    <nly-button variant="primary" id="toggle-btn" @click="toggleModal"
      >Toggle
    </nly-button>

    <nly-modal ref="my-modal" hide-footer title="Using Component Methods">
      <div class="d-block text-center">
        <h3>Hello NlyAdminlteVue</h3>
      </div>
      <nly-button class="mt-3" variant="outlineDanger" block @click="hideModal"
        >hide</nly-button
      >
      <nly-button
        class="mt-2"
        variant="outlineWarning"
        block
        @click="toggleModal"
        >Toggle</nly-button
      >
    </nly-modal>
  </div>
</template>

<script>
  export default {
    methods: {
      showModal() {
        this.$refs["my-modal"].show();
      },
      hideModal() {
        this.$refs["my-modal"].hide();
      },
      toggleModal() {
        this.$refs["my-modal"].toggle("#toggle-btn");
      },
    },
  };
</script>

<!-- show,hide,toggle 显示隐藏.name -->
<!-- nly-modal-modal-hide-show.vue -->

hide() 可以接受一个 trigger 参数 来阻止模态框关闭,具体请查看 阻止关闭

注意

建议使用 $nlyaModal 方法而不是 ref 这种方法

使用 v-model

v-model 的值始终会与 nly-modal 的 显示和隐藏状态同步,你可以用 v-model 来控制模态框的显示和隐藏

使用 v-model 的时候,请不要同时使用 visible , 因为 v-model 是 指向 visible 的。

<template>
  <div>
    <nly-button variant="outlineDanger" @click="modalShow = !modalShow"
      >显示</nly-button
    >

    <nly-modal v-model="modalShow">Hello NlyAdminlteVue</nly-modal>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        modalShow: false,
      };
    },
  };
</script>

<!-- v-model 显示隐藏.name -->
<!-- nly--modal-hide-show.vue -->

使用具名插槽

具体见 具名插槽

将事件发射到 root

您可以将 nlya::show::modal , nlya::hide::modalnlya::toggle::modal 事件发射到$root,其他组件或者元素可以来调用对应的方法来显示和隐藏对应的模态框

第一个参数为对应的上述三个方法,第二个参数对应模态框 id,或 css 元素选择器,第三个元素为需要绑定控制事件的元素,最好用 ref 获取

<template>
  <div>
    <nly-button @click="showModal" variant="outlineDanger" ref="btnShowRoot"
      >show</nly-button
    >
    <nly-button @click="toggleModal" variant="outlineDanger" ref="btnToggleRoot"
      >Toggle</nly-button
    >

    <nly-modal id="modal-root">
      <div class="d-block">Hello NlyAdminlteVue</div>
      <nly-button @click="hideModal" variant="outlineDanger">hide</nly-button>
      <nly-button @click="toggleModal" variant="outlineDanger"
        >Toggle</nly-button
      >
    </nly-modal>
  </div>
</template>

<script>
  export default {
    methods: {
      showModal() {
        this.$root.$emit("nlya::show::modal", "modal-root", "#btnShowRoot");
      },
      hideModal() {
        this.$root.$emit("nlya::hide::modal", "modal-root", "#btnShowRoot");
      },
      toggleModal() {
        this.$root.$emit("nlya::toggle::modal", "modal-root", "#btnToggleRoot");
      },
    },
  };
</script>

<!-- $root 显示隐藏.name -->
<!-- nly-modal-modal-hide-show.vue -->

阻止关闭

可以绑定 .preventDefault() 方法到 ok (确定按钮), cancel (取消按钮), close (modal 头部的关闭按钮), hide 事件上 来阻止 nly-modal 关闭

.preventDefault() 使用的时候,必须是同步事件,不支持异步

<template>
  <div>
    <nly-button v-nly-modal.modal-prevent-closing>Open Modal</nly-button>

    <div class="mt-3">
      提交的姓名:
      <div v-if="submittedNames.length === 0">--</div>
      <ul v-else class="mb-0 pl-3">
        <li v-for="name in submittedNames">{{ name }}</li>
      </ul>
    </div>

    <nly-modal
      id="modal-prevent-closing"
      ref="modal"
      title="提交您的姓名"
      @show="resetModal"
      @hidden="resetModal"
      @ok="handleOk"
    >
      <form ref="form" @submit.stop.prevent="handleSubmit">
        <nly-form-group
          :valid="nameState"
          label="Name"
          label-for="name-input"
          invalid-feedback="姓名必填"
        >
          <nly-form-input
            id="name-input"
            v-model="name"
            :valid="nameState"
            required
          ></nly-form-input>
        </nly-form-group>
      </form>
    </nly-modal>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        name: "",
        nameState: "novalid",
        submittedNames: [],
      };
    },
    methods: {
      checkFormValidity() {
        const valid = this.$refs.form.checkValidity() ? "valid" : "invalid";
        this.nameState = valid;
        return valid;
      },
      resetModal() {
        this.name = "";
        this.nameState = "novalid";
      },
      handleOk(nlyaModalEvt) {
        nlyaModalEvt.preventDefault();
        this.handleSubmit();
      },
      handleSubmit() {
        if (this.checkFormValidity() === "invalid") {
          return;
        }
        this.submittedNames.push(this.name);
        this.$nextTick(() => {
          this.$nlyaModal.hide("modal-prevent-closing");
        });
      },
    },
  };
</script>

<!-- 阻止关闭.name -->
<!-- nly-modal-modal-hide-show.vue -->

注意

  • ok (确定按钮), cancel (取消按钮), colse (modal 头部的关闭按钮) 都是内置的 确定按钮 , 取消按钮 , modal 头部的关闭按钮 触发的. 如果您对这些适用卤具名按钮, 请使用 hide 事件来触发。

ok (确定按钮), cancel (取消按钮), close (modal 头部的关闭按钮), hide 事件 (nlyaModalEvt) 包含以下方法和属性:

Property or Method Type Description
preventDefault() Method 阻止关闭
trigger Property 可以是以下选项: ok (默认的 OK 按钮点击调用 Clicked), cancel (默认的 Cancel 按钮点击调用), esc (按下 Esc 按键调用), backdrop (点击 modal 罩层调用), headerclose (modal 头部 x 关闭按钮调用), 这些应该作为只一个参数传给 hide() 方法, 如果不需要设置,请传入 null 或者不传入, trigger 的使用方法请看下面 trigger 源码
target Property modal 元素
vueTarget property vue 实例的 modal 元素
componentId property modal 的 id

注意

trigger 源码

hide(trigger = "") {
    if (!this.isVisible || this.isClosing) {
        /* istanbul ignore next */
        return;
    }
    this.isClosing = true;
    const hideEvt = this.buildEvent("hide", {
        cancelable: trigger !== "FORCE",
        trigger: trigger || null
    });
    // We emit specific event for one of the three built-in buttons
    if (trigger === "ok") {
        this.$emit("ok", hideEvt);
    } else if (trigger === "cancel") {
        this.$emit("cancel", hideEvt);
    } else if (trigger === "headerclose") {
        this.$emit("close", hideEvt);
    }
    this.emitEvent(hideEvt);
    // Hide if not canceled
    if (hideEvt.defaultPrevented || !this.isVisible) {
        this.isClosing = false;
        // Ensure v-model reflects current state
        this.updateModel(true);
        return;
    }
    // Stop observing for content changes
    if (this._observer) {
        this._observer.disconnect();
        this._observer = null;
    }
    // Trigger the hide transition
    this.isVisible = false;
    // Update the v-model
    this.updateModel(false);
}

使用 grid 布局和 container 布局和 wrapper 布局

nly-modal 中可以任意嵌套 nly-container , nly-row , nly-col , nly-wrapper 系列 布局

Tooltips and popovers

Tooltips 和 popovers 放在 nly-modal 中,当 nly-modal 关闭的时候, Tooltips 和 popovers 会自动关闭。

Tooltips 和 popovers 会自动添加到 modal 元素中,当然您也可以把 Tooltips 和 popovers 添加到指定 id 的元素中, 可以参考 Tooltips 和 popovers 的文档

<div>
  <nly-button v-nly-modal.modalPopover>弹出modal</nly-button>

  <nly-modal id="modalPopover" title="带 popovers 的 modal" ok-only>
    <p>
      这个
      <nly-button v-nly-popover="'modal 中的 popovers!'" title="Popover"
        >按钮</nly-button
      >
      点击弹出 popovers
    </p>
    <p>
      这个
      <a href="#" v-nly-tooltip title="modal 中的tooltip">链接</a>
      鼠标悬浮会弹出 toolptips
    </p>
  </nly-modal>
</div>

<!-- Tooltips 和 popovers.name -->
<!-- Tooltips and popovers.vue -->

懒加载和静态模态框

在默认情况下, modal 是不会渲染在当前元素中的,会渲染在 <body> 的尾部。 nly-modal 不会影响布局,因为他会在元素下面渲染成 <!-- --> 占位符。由于 portal-vue 可以把元素替换到其他任意地方,他可以把多个 nly-modal 渲染到指定目标元素下面。

设置 static prop 为 true时,可以把 nly-modal 渲染到当前元素下面,而不是添加到 <body> 的尾部,且是渲染成一个正常的 html 元素,非 <!-- --> 占位符, 这时候 modal 会影响布局。 如果设置lazy prop 为 true, 即渲染为懒加载模式, modal 会渲染到当前元素,当模态框不显示的时候会渲染成 <!-- --> 占位符。注意 lazy 只有在static prop 为 true时有效。

式样, 选项, 定制

大小

modal 的大小可以由 size prop 來控制。 可选 sm, md, lg

<div>
  <nly-button v-nly-modal.modal-xl variant="primary">xl modal</nly-button>
  <nly-button v-nly-modal.modal-lg variant="primary">lg modal</nly-button>
  <nly-button v-nly-modal.modal-sm variant="primary">sm modal</nly-button>

  <nly-modal id="modal-xl" size="xl" title="Extra Large Modal"
    >Hello Extra Large Modal!</nly-modal
  >
  <nly-modal id="modal-lg" size="lg" title="Large Modal"
    >Hello Large Modal!</nly-modal
  >
  <nly-modal id="modal-sm" size="sm" title="Small Modal"
    >Hello Small Modal!</nly-modal
  >
</div>

<!-- 大小.name -->
<!-- size.vue -->

滚动条

如果 modal 的主体内容太长,超过当前屏幕可见区域,会自动出现滚动条,滚动条是浏览器的滚动条,这时候,不可见区域需要滚动条滚下去才能看到。

<div>
  <nly-button v-nly-modal.modal-tall>滚动加载内容</nly-button>

  <nly-modal id="modal-tall" title="Overflowing Content">
    <p class="my-4" v-for="i in 20" :key="i">
      作者又高又帅,作者大帅比,帅的世界地震
    </p>
  </nly-modal>
</div>

<!-- 滚动条.name -->
<!-- scrolling.vue -->

我们可以设置 scrollabletrue 来给 modal 创建一个滚动条,滚动条会出现在 modal 的 body 中。

<div>
  <nly-button v-nly-modal.modal-scrollable>Launch scrolling modal</nly-button>

  <nly-modal id="modal-scrollable" scrollable title="滚动条加载内容">
    <p class="my-4" v-for="i in 20" :key="i">
      作者又高又帅,作者大帅比,帅的世界地震
    </p>
  </nly-modal>
</div>

<!-- 滚动条.name -->
<!-- scrollable.vue -->

垂直居中

可以设置 centered prop 为 true 来使得 modal 垂直居中

<div>
  <nly-button v-nly-modal.modal-center>垂直居中 modal</nly-button>

  <nly-modal id="modal-center" centered title="BootstrapVue">
    <p class="my-4">垂直居中 modal</p>
  </nly-modal>
</div>

<!-- 垂直居中.name -->
<!-- centered.vue -->

颜色

使用以下 prop 来控制 header, foorer, body 的颜色: header-bg-variant, header-text-variant, body-bg-variant, body-text-variant, footer-bg-variant, footer-text-variant props. 使用 adminlte 的主体颜色, 比如: danger, warning, info, success, dark, light

<template>
  <div>
    <nly-button @click="show=true" variant="primary">Show Modal</nly-button>

    <nly-modal
      v-model="show"
      title="Modal Variants"
      :header-bg-variant="headerBgVariant"
      :header-text-variant="headerTextVariant"
      :body-bg-variant="bodyBgVariant"
      :body-text-variant="bodyTextVariant"
      :footer-bg-variant="footerBgVariant"
      :footer-text-variant="footerTextVariant"
    >
      <nly-container fluid>
        <nly-row class="mb-1 text-center">
          <nly-col cols="3"></nly-col>
          <nly-col>Background</nly-col>
          <nly-col>Text</nly-col>
        </nly-row>

        <nly-row class="mb-1">
          <nly-col cols="3">Header</nly-col>
          <nly-col>
            <nly-form-select
              v-model="headerBgVariant"
              :options="variants"
            ></nly-form-select>
          </nly-col>
          <nly-col>
            <nly-form-select
              v-model="headerTextVariant"
              :options="variants"
            ></nly-form-select>
          </nly-col>
        </nly-row>

        <nly-row class="mb-1">
          <nly-col cols="3">Body</nly-col>
          <nly-col>
            <nly-form-select
              v-model="bodyBgVariant"
              :options="variants"
            ></nly-form-select>
          </nly-col>
          <nly-col>
            <nly-form-select
              v-model="bodyTextVariant"
              :options="variants"
            ></nly-form-select>
          </nly-col>
        </nly-row>

        <nly-row>
          <nly-col cols="3">Footer</nly-col>
          <nly-col>
            <nly-form-select
              v-model="footerBgVariant"
              :options="variants"
            ></nly-form-select>
          </nly-col>
          <nly-col>
            <nly-form-select
              v-model="footerTextVariant"
              :options="variants"
            ></nly-form-select>
          </nly-col>
        </nly-row>
      </nly-container>

      <template v-slot:modal-footer>
        <div class="w-100">
          <p class="float-left">Modal Footer Content</p>
          <nly-button
            variant="primary"
            size="sm"
            class="float-right"
            @click="show=false"
          >
            Close
          </nly-button>
        </div>
      </template>
    </nly-modal>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        show: false,
        variants: [
          "primary",
          "secondary",
          "success",
          "warning",
          "danger",
          "info",
          "light",
          "dark",
        ],
        headerBgVariant: "dark",
        headerTextVariant: "light",
        bodyBgVariant: "light",
        bodyTextVariant: "dark",
        footerBgVariant: "warning",
        footerTextVariant: "dark",
      };
    },
  };
</script>

<!-- 颜色.name -->
<!-- variant.vue -->

隐藏罩层

<div>
  <nly-button v-nly-modal.modal-no-backdrop>打开</nly-button>

  <nly-modal
    id="modal-no-backdrop"
    hide-backdrop
    content-class="shadow"
    title="NlyAdminlteVue"
  >
    <p class="my-2">给modal添加了css 类 <code>'shadow'</code></p>
  </nly-modal>
</div>

<!-- 隐藏罩层.name -->
<!-- hide-backdrop.vue -->

关闭 出现/消失 动画

可以给 nly-moodal 设置 prop no-fade 来关闭 modal 出现或者消失时的动画

可以设置 button-size prop 为 sm 显示小按钮或者设置为 lg 显示大按钮

<div>
  <nly-button v-nly-modal.modal-footer-sm>小按钮</nly-button>
  <nly-button v-nly-modal.modal-footer-lg>大按钮</nly-button>

  <nly-modal id="modal-footer-sm" title="NlyAdminlteVue" button-size="sm">
    <p class="my-2">小按钮</p>
  </nly-modal>

  <nly-modal id="modal-footer-lg" title="NlyAdminlteVue" button-size="lg">
    <p class="my-2">大按钮</p>
  </nly-modal>
</div>

<!-- 按钮大小.name -->
<!-- button-size.vue -->

可以通过设置 cancel-disabledok-disabled 来禁用 footer 中的 OK 和 CANCEL 按钮

可以设置 busy prop 来使用 OK 和 CANCEL 按钮 同时不可用

自定义设置 和 插槽

modal 有以下插槽

Slot Optionally Scoped Description
default Yes 默认插槽,modal 的主体内容
modal-title Yes title 插槽
modal-header Yes header 插槽, 包括 头部关闭按钮
modal-footer Yes footer 插槽,包括 OK CANCEL 按钮
modal-ok No OK 按钮插槽
modal-cancel No CANCEL 按钮插槽
modal-header-close No 头头部关闭按钮插槽

modal 插槽有以下方法

Method or Property Description
ok() 关闭 modal 和触发 okhide 事件, 使用 nlyaModalEvent.trigger = 'ok'
cancel() 关闭 modal 和触发 cancelhide 事件, 使用 nlyaModalEvent.trigger = 'cancel'
close() 关闭 modal 和触发 close and hide 事件, 使用 nlyaModalEvent.trigger = 'headerclose'
hide(trigger) 关闭 modal 和触发 hide 事件, 使用 nlyaModalEvent.trigger = trigger (trigger is optional)
visible modal 的可见状态. 设置 true 弹出 modal, 设置 false 关闭 modal

使用 scoped slots

<template>
  <nly-button @click="$nlyaModal.show('modal-scoped')">打开</nly-button>

  <nly-modal id="modal-scoped">
    <template v-slot:modal-header="{ close }">
      <nly-button size="sm" variant="outline-danger" @click="close()">
        关闭
      </nly-button>
      <h5>footer</h5>
    </template>

    <template v-slot:default="{ hide }">
      <p>body 按钮</p>
      <nly-button @click="hide()">关闭 modal</nly-button>
    </template>

    <template v-slot:modal-footer="{ ok, cancel, hide }">
      <b>Custom Footer</b>
      <nly-button size="sm" variant="success" @click="ok()">
        OK
      </nly-button>
      <nly-button size="sm" variant="danger" @click="cancel()">
        Cancel
      </nly-button>
      <nly-button size="sm" variant="outlineSecondary" @click="hide('forget')">
        Forget it
      </nly-button>
    </template>
  </nly-modal>
</template>

<!-- scoped slots.name -->
<!-- scoped slots.vue -->

多个模式

nly-modal 支持多个模态框

设置 no-stackingtrue 可以使得在另一个模态框出现之前, 在他前面的模态框会隐藏掉

<div>
  <nly-button v-nly-modal.modal-multi-1>打开第一个 Modal</nly-button>

  <nly-modal id="modal-multi-1" size="lg" title="Modal 1" ok-only no-stacking>
    <p class="my-2">First Modal</p>
    <nly-button v-nly-modal.modal-multi-2>打开第二个modal</nly-button>
  </nly-modal>

  <nly-modal id="modal-multi-2" title="Modal 2" ok-only>
    <p class="my-2">第二个 Modal</p>
    <nly-button v-nly-modal.modal-multi-3 size="sm"
      >打开第三个 Modal</nly-button
    >
  </nly-modal>

  <nly-modal id="modal-multi-3" size="sm" title="Third Modal" ok-only>
    <p class="my-1">第三个modal</p>
  </nly-modal>
</div>

<!-- 多个模式.name -->
<!-- modal-multi.vue -->

注意 请尽量不要使用嵌套 nly-modal, 因为这样会影响布局,尤其是静态 modal

模态消息框

modal 可以渲染成消失提示框

Method Description
this.$nlyaModal.msgBoxOk(message, options) 打开 msg box modal
this.$nlyaModal.msgBoxConfirm(message, options) 打开 msgBoxConfirm modal

option 是可以设置对象,用来设置标题 和 设置 渲染为 msgBoxOk 的 modal, 两种方法都返回一个 Promise(IE 11 和较旧的浏览器需要的 polyfill),当 modal 隐藏时,该解析为一个值。.msgBoxOk()始终解析为值 true,而.msgBoxConfirm()解析为 true(按下“确定”按钮),false(按下“取消”按钮)或 null(如果通过背景幕点击,Esc 按下或其他方式关闭了模式,则解析为)。

如果 message ·没有提供,则这两种方法都将立即返回 value undefined。

您可以使用.then(..).catch(...)或异步 await 代码样式(异步 await 需要浏览器或编译器)。

OK message box

<template>
  <div>
    <div class="mb-2">
      <nly-button @click="showMsgBoxOne">Simple msgBoxOk</nly-button>
      Return value: {{ String(boxOne) }}
    </div>
    <div class="mb-1">
      <nly-button @click="showMsgBoxTwo">msgBoxOk with options</nly-button>
      Return value: {{ String(boxTwo) }}
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        boxOne: "",
        boxTwo: "",
      };
    },
    methods: {
      showMsgBoxOne() {
        this.boxOne = "";
        this.$nlyaModal
          .msgBoxOk("Action completed")
          .then((value) => {
            this.boxOne = value;
          })
          .catch((err) => {
            // An error occurred
          });
      },
      showMsgBoxTwo() {
        this.boxTwo = "";
        this.$nlyaModal
          .msgBoxOk("Data was submitted successfully", {
            title: "Confirmation",
            size: "sm",
            buttonSize: "sm",
            okVariant: "success",
            headerClass: "p-2 border-bottom-0",
            footerClass: "p-2 border-top-0",
            centered: true,
          })
          .then((value) => {
            this.boxTwo = value;
          })
          .catch((err) => {
            // An error occurred
          });
      },
    },
  };
</script>

<!-- MsgBox.name -->
<!-- MsgBox,.vue -->

Confirm message box

<template>
  <div>
    <div class="mb-2">
      <nly-button @click="showMsgBoxOne">Simple msgBoxConfirm</nly-button>
      Return value: {{ String(boxOne) }}
    </div>
    <div class="mb-1">
      <nly-button @click="showMsgBoxTwo">msgBoxConfirm with options</nly-button>
      Return value: {{ String(boxTwo) }}
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        boxOne: "",
        boxTwo: "",
      };
    },
    methods: {
      showMsgBoxOne() {
        this.boxOne = "";
        this.$nlyaModal
          .msgBoxConfirm("Are you sure?")
          .then((value) => {
            this.boxOne = value;
          })
          .catch((err) => {
            // An error occurred
          });
      },
      showMsgBoxTwo() {
        this.boxTwo = "";
        this.$nlyaModal
          .msgBoxConfirm("Please confirm that you want to delete everything.", {
            title: "Please Confirm",
            size: "sm",
            buttonSize: "sm",
            okVariant: "danger",
            okTitle: "YES",
            cancelTitle: "NO",
            footerClass: "p-2",
            hideHeaderClose: false,
            centered: true,
          })
          .then((value) => {
            this.boxTwo = value;
          })
          .catch((err) => {
            // An error occurred
          });
      },
    },
  };
</script>
<!-- MsgBox.name -->
<!-- msgBoxConfirm,.vue -->

注意事项

  • this.$nlyaModal 注入只有在引入整个 NlyAdminlteVue 或者 ModalPlugin 插件才有效。 引入 nly-modal 是无效的,如果只需要使用 this.$nlyaModal, 请引入 VNlyModalPlugin

  • 每一个 Vue 虚拟 dom 都会创建一个 $nlyaModal, 注入到 mixin, 所有不能直接使用 Vue.prototype 来访问, 因为他需要使用实例的 this$root 上下文

  • message box 需要支持 Promise 的浏览器, 如果浏览器不支持, 请使用 polyfill,这会提供 Promise 支持,否则会返回 undefined

  • message box 是 nly-modal 组件的拓展,他能支持 nly-modal 的绝大部分 props, 这些 prop 需要使用 camelCase 格式。但是下面这些 prop 会出现异常,请谨慎使用。lazy, static, busy, visible, noStacking, okOnly, okDisabledcancelDisabled.

  • title (titleHtml) 不在 设置(options)中,将不会显示 header

  • title (titleHtml) 在设置中, header 中的关闭(x)按钮不会显示,您可以在 options 中设置 hideHeaderClose: false 来强制显示 headr 中的关闭按钮

  • 如果 message box 在隐藏之前被关闭或者销毁,会抛出有个 promise rejection error,所以通常会有一个 .catch(errHandler) 在对应的函数中,可以使用 await 一类的异步代码

  • 当你使用 Vue Router 时, 如果 message box 在路由切换的时候没有隐藏起来,会关闭并抛出错误,如果你希望这个 message box 在切换路由的时候不被销毁,使用 this.$root.$nlyaModal 代替 this.$nlyaModal.

  • ssr 渲染中间,是无法生成 message box 的

  • message box 目前不支持 HTM L 字符串,但是,您可以通过传递 VNodes 数组,来实现

  • message box 内容的自定义。您可以使用 Vue 的 this.$createElement 方法生成 VNode。对于 modal title(通过将 VNode 传递到 title 选项),OK 按钮文本(通过 okTitle 选项)和 CANCEL 按钮文本(通过 cancelTitle 选项)也可以这样做。

Message box 的高级用法

使用 this.$nlyaModal.msgBoxOk(...) 或者 this.$nlyaModal.msgBoxConfirm(...) 生成 modal 时,如果需要展示更多的主体内容,除了 注意事项 说的事项之外,您可以构造一个 VNodes 传入 modal 来作为主体内容

<template>
  <div>
    <nly-button @click="showMsgOk"
      >Show OK message box with custom content</nly-button
    >
  </div>
</template>

<script>
  export default {
    methods: {
      showMsgOk() {
        const h = this.$createElement;
        const titleVNode = h("div", {
          domProps: { innerHTML: "Title from <i>HTML<i> string" },
        });
        const messageVNode = h("div", { class: ["foobar"] }, [
          h("p", { class: ["text-center"] }, [
            " Flashy ",
            h("strong", "msgBoxOk"),
            " message ",
          ]),
          h("p", { class: ["text-center"] }, [h("nly-spinner")]),
          h("img", {
            class: "img-thumbnail img-fluid rounded-circle mx-auto d-block",
            attrs: {
              src: "https://picsum.photos/id/20/250/250",
            },
          }),
        ]);
        this.$nlyaModal.msgBoxOk([messageVNode], {
          title: [titleVNode],
          buttonSize: "sm",
          centered: true,
          size: "sm",
        });
      },
    },
  };
</script>

<!-- 高级用法.name -->
<!-- advanced usage.vue -->

通过 $root 事件 来监听 modal 的状态

export default {
  mounted() {
    this.$root.$on("nlya::modal::show", (nlyaEvent, modalId) => {
      console.log("Modal is about to be shown", nlyaEvent, modalId);
    });
  },
};

辅助功能

nly-modal 提供了几种辅助功能,比如自动聚焦,返回焦点,键盘操作和 aria-* 属性

ARIA 属性

在大多数情况下 modal 的 aria-labelledbyaria-describedby属性会自动显示

  • 如果您隐藏了 header,或者 没有提供 title prop,或者 自定义了一个 header, aria-labelledby 属性将不会自动生成。如果您需要在视觉上隐藏标标题,而在屏幕阅读器上显示标题, 您可以设置 title-sr-only prop, 如果没有 header,您可以给 aria-label prop 传入一个字符串值来代替

  • aria-describedby 属性是渲染在 modal 的主体上的

  • 如果 aria-label 传入了一个值,即使你的 modal 有 header 和 title,aria-labelledby 也会失效,

打开 modal 自动聚焦

nly-modal 在打开的时候会自动聚焦到 modal 主体上

您可以通过监听 nly-modalshown 事件来调用想要聚焦的元素的 focus() 事件来使得 modal 打开就聚焦在对应的元素中。

<nly-modal @shown="focusMyElement">
  <div>
    <nly-button>自动聚焦</nly-button>
  </div>

  <div>
    <nly-form-input></nly-form-input>
  </div>

  <div>
    <!-- Element to gain focus when modal is opened -->
    <nly-form-input ref="focusThis"></nly-form-input>
  </div>

  <div>
    <nly-form-input></nly-form-input>
  </div>
</nly-modal>
export default {
  methods: {
    focusMyElement() {
      this.$refs.focusThis.focus();
    },
  },
};

如果你使用 nly-form-* 组件, modal 打开的时候会自动聚焦到 这些组件上。 如果使用了 static prop,但是没有设置 lazy prop, autofocus prop 会失效

如果您想自动聚焦到 cancel, ok, close 按钮上, 请设置 auto-focus-button,值为对应的按钮名称。 modal 打开的时候,会自动聚焦到对应的按钮上面,如果这个按钮被隐藏了,那么拒绝效果会失效。

关闭 modal 聚焦到指定元素

您可以设置 return-focus 来让 modal 关闭之后自动聚焦到对应的元素上。传入值可以为:

  • CSS 选择器

  • 组件的 refs

  • dom 选择器

如果传入的对象是不可聚焦的, 这时候聚焦的元素会由浏览器自己选择

这个 prop 在使用 nly-modalshow(), hide() 方法 和 v-model 的时候特别方便,且优先级别高于其他聚焦 foucs prop

自动聚焦

nly-modal 如果是使用指令 v-nly- modal 显示/隐藏的, 将会自动聚焦到绑定指令的元素上,但是如果设置了 return-foucs prop,则会聚焦到 return-foucs 指定的元素上

通过事件来聚焦到指定的元素上

使用 nly::show::modal (必须是从 root 上发出的)事件,可以在第二个参数传入值,使得 modal 关闭时聚焦到对应的元素上。 第二个参数传入值类型应该跟 return-focus 是一样的。

this.$root.$emit("nly::show::modal", "modal-1", "#focusThisOnClose");

** 注意 ** 如果 return-focus prop 设置了值, 这个事件设置是无效的

组件参数

<nly-modal>

props 参数

props (Click to sort Ascending)类型默认值描述
id
Stringnull设置id
size
String'md'大小,可选xs,sm,md,lg,xl
centered
Booleanfalsemodal 居中显示
scrollable
Booleanfalse允许 modal body 出现滚动条, 负责滚动条是浏览器的滚动条
button-size
String设置footer的按钮大小, 可选'sm', 'md', 'lg', 'md'为默认大小
no-stacking
Booleanfalse设置 no-stacking,在其他 modal 将要打开的之前,设置no-stacking的modal会自动关闭
no-fade
Booleanfalse无动画,设置true关闭动画
no-close-on-backdrop
Booleanfalse设置 no-close-on-backdrop, 点击背景罩层不会关闭 modal
no-close-on-esc
Booleanfalse设置 no-close-on-esc,按键盘ESC键不会关闭 modal
no-enforce-focus
Booleanfalse强制禁用聚焦功能
ignore-enforce-focus-selector
Array or String''ignore-enforce-focus-selector 是一个css 选择器,如果需要在打开modal的时候聚焦到其他元素上, 可以把其他需要聚焦的元素的 css 类添加到 prop ignore-enforce-focus-selector中
title
String''标题文字
title-html
谨慎使用
String用 html 字符串替换标题
title-tag
String'h5'标题的标签
title-class
String or Array or Object标题的 css 类
title-sr-only
Booleanfalse设置 true ,视觉上不显示标题,屏幕阅读器上显示
aria-label
String给元素设置 aria-label 属性
header-bg-variant
Stringnullheader 背景颜色
header-border-variant
Stringnullheder边框颜色
header-text-variant
Stringnullheader 文字 颜色
header-close-variant
Stringnullheader 关闭按钮颜色
header-class
String or Array or Objectheader的css类
body-bg-variant
Stringnullbody 背景颜色
body-text-variant
Stringnullbody 文字颜色
modal-class
String or Array or Object添加到 '.modal' 元素的 css 类
dialog-class
String or Array or Object添加到 '.dialog-class' 元素的 css 类
content-class
String or Array or Object添加到 '.content-class' 元素的 css 类
body-class
String or Array or Objectbody的css类
footer-bg-variant
Stringnullfooter 背景颜色
footer-border-variant
Stringnullfooter边框颜色
footer-text-variant
Stringnullfooter 文字颜色
footer-class
String or Array or Objectfooter的css类
hide-header
Booleanfalse隐藏头部
hide-footer
Booleanfalse隐藏底部
hide-header-close
Booleanfalse隐藏头部关闭按钮
hide-backdrop
Booleanfalse隐藏罩层
ok-only
Booleanfalse不渲染底部默认的 cancel 按钮
ok-disabled
Booleanfalse设置底部默认的 ok 按钮为禁用
cancel-disabled
Booleanfalse设置底部默认的 cancel 按钮为禁用
visible
v-model
Booleanfalsemodal的可见状态
return-focus
or String or Objectnull关闭 modal 聚焦元素, 传入用为css选择器或者dom选择器等
header-close-content
String'&times;'头部关闭按钮的主体内容
header-close-label
String'Close'头部关闭按钮的 aria-label 值
cancel-title
String'Cancel'footer cancel 按钮的文本内容
cancel-title-html
谨慎使用
String替换 footer cancel 标题的 html 字符串
ok-title
String'OK'footer ok 按钮的文本内容
ok-title-html
谨慎使用
String替换 footer ok 标题的 html 字符串
cancel-variant
String'secondary'footer cancel 按钮的 颜色
ok-variant
String'primary'footer ok 按钮的 颜色
lazy
Booleanfalse懒加载模式
busy
Booleanfalsemodal 加载中
static
Booleanfalse渲染成静态模式,直接添加到对应的元素中或者下面,否则会被portal-vue渲染到html body的尾部
auto-focus-button
Stringnull自动聚焦到 modal 自带的按钮上,可选 ok, cancel, close

注意: 支持 (*-html) html 字符串的 prop 可能会引起 脚本攻击 (XSS), 当用户使用这类 prop 的时候,您应该谨慎 处理 这类值

v-model

PropertyEvent
visiblechange

Slots

Slot NameScopedDescription
modal-header modal 的 头部插槽,使用插槽会移除对应的 cloase 按钮
modal-title modal 的 title 插槽,如果使用了 `modal-header`, `modal-title` 插槽不会生效
modal-footer modal footer 插槽. 会移除默认的 `ok` 按钮和 `cancal` 按钮
modal-header-close Nomodal 的头部关闭按钮插槽. 如果使用了 `modal-header` 插槽, `modal-header-close` 会失效
modal-ok Nook 按钮插槽
modal-cancel Nocancel 按钮插槽
modal-backdrop Nomodal 罩层插槽
default 默认插槽

Events

EventArgumentsDescription
change
  1. isVisible - modal的可见状态, `true` 是现实状态, `false`是隐藏状态
修改modal的状态, 会更新 v-model
show
  1. nlyaModalEvt - NlyaModalEvent 对象. 回调 `nlyaModalEvt.preventDefault()` 可以阻止 modal 显示
在 modal 展示之前发出事件
shown
  1. nlyaModalEvt - NlyaModalEvent 对象
在 modal 显示之后发出事件
hide
  1. nlyaModalEvt - NlyaModalEvent 对象, 注入 `nlyaModalEvt.trigger` 可以查找触发隐藏的事件. 使用 `nlyaModalEvt.preventDefault()` 可以阻止 modal 隐藏
在 modal 隐藏之前发出的事件
hidden
  1. nlyaModalEvt - NlyaModalEvent 对象,
隐藏 modal 之后触发的事件
ok
  1. nlyaModalEvt - NlyaModalEvent 对象, 使用 `nlyaModalEvt.preventDefault()` 可以阻止 modal 隐藏
点击默认的 ok 按钮触发 modal 关闭, 可以自定义按钮其他逻辑, 关闭逻辑不会被覆盖
cancel
  1. nlyaModalEvt - NlyaModalEvent 对象, 使用 `nlyaModalEvt.preventDefault()` 可以阻止 modal 取消
点击默认的 cancel 按钮触发 modal 取消, 可以自定义按钮其他逻辑, 取消逻辑不会被覆盖
close
  1. nlyaModalEvt - NlyaModalEvent 对象, 使用 `nlyaModalEvt.preventDefault()` 可以阻止 modal 关闭
点击默认的 close 按钮触发 modal 关闭, 可以自定义按钮其他逻辑, 逻辑不会被覆盖
nlya::modal::show
  1. nlyaModalEvt - NlyaModalEvent 对象, 使用 `nlyaModalEvt.preventDefault()` 阻止 modal 显示
  2. modalId - Modal ID
在 modal 显示之前触发在 `$root` 上的 emit 事件
nlya::modal::shown
  1. nlyaModalEvt - NlyaModalEvent 对象
  2. modalId - Modal ID
在 modal 显示之后触发在 `$root` 上的 emit 事件
nlya::modal::hide
  1. nlyaModalEvt - NlyaModalEvent 对象,使用 `nlyaModalEvt.preventDefault()` 阻止隐藏
  2. modalId - Modal ID
在 modal 隐藏之前触发在 `$root` 上的 emit 事件
nlya::modal::hidden
  1. nlyaModalEvt - NlyaModalEvent 对象,
  2. modalId - modal ID
在 modal 隐藏之后触发在 `$root` 上的 emit 事件

$root event listeners

你可以通过 $root emit以下事件来控制组件(指令) <nly-modal>

EventArgumentsDescription
nlya::show::modal

modalId - 需要显示的 Modal ID

elIDtoFocusOnClose - dom 元素或者 css 选择器, 当 modal 关闭之后,会自动聚焦到对应的元素上

从 `$root` 上 emit 事件来显示对应 id 的 modal
nlya::hide::modal

modalId - 需要隐藏的 modal 的id

从 `$root` 上 emit 事件来隐藏对应 id 的 modal
nlya::toggle::modal

modalId - 需要切换状态的 modal 的id

elIDtoFocusOnClose - dom 元素或者 css 选择器, 当 modal 切换状态之后,会自动聚焦到对应的元素上

切换对应 id 的 modal 的可见状态

单个组件导入

你可以从下表给出的导出路径和导出名称导入单个组件包

组件导出名称导出路径
<nly-modal>NlyModalnly-adminlte-vue

例子

import { NlyModal } from 'nly-adminlte-vue'
Vue.component('nly-modal', NlyModal)

单个指令导出

你可以从下表给出的导出路径和导出名称导入单个指令包

指令导出名称导出路径
v-nly-modalVNlyModalnly-adminlte-vue

例子

import { VNlyModal } from 'nly-adminlte-vue'
// Note: Vue automatically prefixes the directive name with 'v-'
Vue.directive('nly-modal', VNlyModal)

导出作为插件

导出的插件包括上表中列出的组件 和指令. 插件同样包含上表中所有组件的简称.

导出名称导出路径
ModalPluginnly-adminlte-vue

这个插件会自动包括以下插件:

  • VNlyModalPlugin

例子

import { ModalPlugin } from 'nly-adminlte-vue'
Vue.use(ModalPlugin)