模态

模态是简化但灵活的对话框提示,由 JavaScript 和 CSS 提供支持。它们支持多种用例,从用户通知到完全自定义的内容,并具有许多有用的子组件、大小、变体、辅助功能等。

<div>
  <b-button v-b-modal.modal-1>Launch demo modal</b-button>

  <b-modal id="modal-1" title="BootstrapVue">
    <p class="my-4">Hello from modal!</p>
  </b-modal>
</div>

<!-- b-modal.vue -->

概述

<b-modal> 默认情况下,页脚中有一个 确定取消 按钮。可以通过设置组件上的各种属性来自定义这些按钮。你可以自定义按钮的大小,禁用按钮,隐藏 取消 按钮(即 ok-only),使用 ok-variantcancel-variant 属性选择一个变体(例如 danger 表示红色的确定按钮),并使用 ok-titlecancel-title 属性或使用命名插槽 modal-okmodal-cancel 提供自定义按钮内容。

<b-modal> 支持 ESC 关闭(默认启用)、背景点击关闭(默认启用)以及页眉中的 X 关闭按钮(默认启用)。可以通过分别设置属性 no-close-on-escno-close-on-backdrophide-header-close 来禁用这些功能。

你可以通过命名插槽 modal-title 覆盖模态标题,通过 modal-header 插槽完全覆盖页眉,并通过 modal-footer 插槽完全覆盖页脚。

注意:使用 modal-footer 插槽时,默认的 确定取消 按钮将不会出现。此外,如果你使用 modal-header 插槽,默认的页眉 X 关闭按钮将不会出现,你也不可以使用 modal-title 插槽。

模态不会在显示之前在文档中呈现其内容(延迟呈现)。模态在可见时呈现为 附加到 <body> 元素。由于 <b-modal> 组件始终呈现为占位符注释节点 (<!---->),因此其放置不会影响布局。你可以通过使用 static 属性 恢复到旧版 BootstrapVue 的行为。

切换模态可见性

有几种方法可以用来切换 <b-modal> 的可见性。

使用 v-b-modal 指令

其他元素可以使用 v-b-modal 指令轻松显示模态框。

<div>
  <!-- Using modifiers -->
  <b-button v-b-modal.my-modal>Show Modal</b-button>

  <!-- Using value -->
  <b-button v-b-modal="'my-modal'">Show Modal</b-button>

  <!-- The modal -->
  <b-modal id="my-modal">Hello From My Modal!</b-modal>
</div>

<!-- b-modal-directive.vue -->

此方法会在模态框关闭后自动将焦点返回到触发元素(类似于默认 Bootstrap 功能)。切换模态框可见性的其他方法可能需要额外的代码来实现此辅助功能。

有关详细信息,请参阅下面的 辅助功能 部分。

使用 this.$bvModal.show()this.$bvModal.hide() 实例方法

当 BootstrapVue 安装为插件,或使用了 ModalPlugin 插件时,BootstrapVue 会将 $bvModal 对象注入到每个 Vue 实例(组件、应用)中。 this.$bvModal 公开了多个方法,其中两个用于显示和隐藏模态框

方法 说明
this.$bvModal.show(id) 显示具有指定 id 的模态框
this.$bvModal.hide(id) 隐藏具有指定 id 的模态框

这两个方法在调用后立即返回。

<div>
  <b-button id="show-btn" @click="$bvModal.show('bv-modal-example')">Open Modal</b-button>

  <b-modal id="bv-modal-example" hide-footer>
    <template #modal-title>
      Using <code>$bvModal</code> Methods
    </template>
    <div class="d-block text-center">
      <h3>Hello From This Modal!</h3>
    </div>
    <b-button class="mt-3" block @click="$bvModal.hide('bv-modal-example')">Close Me</b-button>
  </b-modal>
</div>

<!-- b-modal-bv-modal-hide-show.vue -->

this.$bvModal 对象还用于显示 模态框消息

使用 show()hide()toggle() 组件方法

可以使用 ref 属性访问模态框,然后调用 show()hide()toggle() 方法。

<template>
  <div>
    <b-button id="show-btn" @click="showModal">Open Modal</b-button>
    <b-button id="toggle-btn" @click="toggleModal">Toggle Modal</b-button>

    <b-modal ref="my-modal" hide-footer title="Using Component Methods">
      <div class="d-block text-center">
        <h3>Hello From My Modal!</h3>
      </div>
      <b-button class="mt-3" variant="outline-danger" block @click="hideModal">Close Me</b-button>
      <b-button class="mt-2" variant="outline-warning" block @click="toggleModal">Toggle Me</b-button>
    </b-modal>
  </div>
</template>

<script>
  export default {
    methods: {
      showModal() {
        this.$refs['my-modal'].show()
      },
      hideModal() {
        this.$refs['my-modal'].hide()
      },
      toggleModal() {
        // We pass the ID of the button that we want to return focus to
        // when the modal has hidden
        this.$refs['my-modal'].toggle('#toggle-btn')
      }
    }
  }
</script>

<!-- b-modal-methods.vue -->

hide() 方法接受一个可选的字符串 trigger 参数,用于定义触发模态框关闭的原因。有关详细信息,请参阅下面的 防止关闭 部分。

注意:建议使用前面部分中提到的 this.$bvModal.show()this.$bvModal.hide() 方法,而不是使用 $ref 方法。

使用 v-model 属性

v-model 属性始终与 <b-modal> 可见状态自动同步,并且可以使用 v-model 显示/隐藏。

<template>
  <div>
    <b-button @click="modalShow = !modalShow">Open Modal</b-button>

    <b-modal v-model="modalShow">Hello From Modal!</b-modal>
  </div>
</template>

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

<!-- b-modal-v-model.vue -->

使用 v-model 属性时,不要同时使用 visible 属性。

使用作用域插槽范围方法

请参阅 使用插槽进行自定义渲染 部分,了解如何使用传递给作用域插槽的各种方法来关闭模态框。

在 $root 上发出事件

您可以在 $root 上发出 bv::show::modalbv::hide::modalbv::toggle::modal 事件,第一个参数设置为模态框的 ID。第二个参数(可选)可以指定模态框关闭后要返回焦点的元素。第二个参数可以是 CSS 选择器、元素引用或组件引用(组件的根元素将获得焦点)。

<div>
  <b-button @click="showModal" ref="btnShow">Open Modal</b-button>
  <b-button @click="toggleModal" ref="btnToggle">Toggle Modal</b-button>

  <b-modal id="modal-1">
    <div class="d-block">Hello From My Modal!</div>
    <b-button @click="hideModal">Close Me</b-button>
    <b-button @click="toggleModal">Toggle Me</b-button>
  </b-modal>
</div>
export default {
  methods: {
    showModal() {
      this.$root.$emit('bv::show::modal', 'modal-1', '#btnShow')
    },
    hideModal() {
      this.$root.$emit('bv::hide::modal', 'modal-1', '#btnShow')
    },
    toggleModal() {
      this.$root.$emit('bv::toggle::modal', 'modal-1', '#btnToggle')
    }
  }
}

注意:建议使用 this.$bvModal.show()this.$bvModal.hide() 方法(在前一部分中提到),而不是发出 $root 事件。

防止关闭

要防止 <b-modal> 关闭(例如,当验证失败时),您可以调用传递给 ok确定按钮)、cancel取消按钮)、close(模态框标题关闭按钮)和 hide 事件处理程序的事件对象的 .preventDefault() 方法。请注意,使用 .preventDefault() 时,必须同步调用,因为不支持异步。

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

    <div class="mt-3">
      Submitted Names:
      <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>

    <b-modal
      id="modal-prevent-closing"
      ref="modal"
      title="Submit Your Name"
      @show="resetModal"
      @hidden="resetModal"
      @ok="handleOk"
    >
      <form ref="form" @submit.stop.prevent="handleSubmit">
        <b-form-group
          label="Name"
          label-for="name-input"
          invalid-feedback="Name is required"
          :state="nameState"
        >
          <b-form-input
            id="name-input"
            v-model="name"
            :state="nameState"
            required
          ></b-form-input>
        </b-form-group>
      </form>
    </b-modal>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        name: '',
        nameState: null,
        submittedNames: []
      }
    },
    methods: {
      checkFormValidity() {
        const valid = this.$refs.form.checkValidity()
        this.nameState = valid
        return valid
      },
      resetModal() {
        this.name = ''
        this.nameState = null
      },
      handleOk(bvModalEvent) {
        // Prevent modal from closing
        bvModalEvent.preventDefault()
        // Trigger submit handler
        this.handleSubmit()
      },
      handleSubmit() {
        // Exit when the form isn't valid
        if (!this.checkFormValidity()) {
          return
        }
        // Push the name to submitted names
        this.submittedNames.push(this.name)
        // Hide the modal manually
        this.$nextTick(() => {
          this.$bvModal.hide('modal-prevent-closing')
        })
      }
    }
  }
</script>

<!-- b-modal-prevent-closing.vue -->

注意:事件 okcancelclose 分别由模态框内置的确定取消和标题关闭(X)按钮发出。如果您在 modal-footer 插槽中提供了自己的按钮或隐藏了页脚,则默认情况下不会发出这些事件。在这种情况下,请使用 hide 事件来控制模态框关闭的取消。即使发出了 okcancelclose,事件 hide 也会始终发出。

okcancelclosehide 事件对象 (BvModalEvent) 包含多个属性和方法

属性或方法 类型 说明
preventDefault() 方法 调用时防止模态关闭
触发器 属性 将是下列之一:ok(默认确定已单击)、cancel(默认取消已单击)、esc(如果按下 Esc 键)、backdrop(如果单击背景)、headerclose(如果单击页眉 X 按钮)、第一个提供给 hide() 方法的参数,或 null
目标 属性 对模态元素的引用
vueTarget 属性 对模态的 Vue VM 实例的引用
componentId 属性 模态的 ID

你可以通过向组件的 hide() 方法传递参数来设置 trigger 的值,以便进行高级控制(即检测触发模态隐藏的按钮或操作)。

注意:仅当 hide() 的参数严格为 'ok''cancel''headerclose' 时,才会发出 okcancelclose 事件。传递给 hide() 的参数将放入事件对象的 trigger 属性中。

使用网格

通过在模态主体中嵌套 <b-container fluid> 来在模态中使用 Bootstrap 网格系统。然后,使用常规网格系统 <b-row>(或 <b-form-row>)和 <b-col>,就像在其他任何地方一样。

工具提示和弹出框

可以根据需要在模态中放置工具提示和弹出框。当模态关闭时,其中的任何工具提示和弹出框也会自动消失。工具提示和弹出框会自动附加到模态元素(以确保正确的 z 索引),尽管你可以通过指定容器 ID 来覆盖附加的位置(有关详细信息,请参阅工具提示和弹出框文档)。

<div>
  <b-button v-b-modal.modalPopover>Show Modal</b-button>

  <b-modal id="modalPopover" title="Modal with Popover" ok-only>
    <p>
      This
      <b-button v-b-popover="'Popover inside a modal!'" title="Popover">Button</b-button>
      triggers a popover on click.
    </p>
    <p>
      This <a href="#" v-b-tooltip title="Tooltip in a modal!">Link</a> will show a tooltip on
      hover.
    </p>
  </b-modal>
</div>

<!-- b-modal-popover.vue -->

延迟加载和静态模态

默认情况下,模态不会在显示之前在文档中呈现其内容(延迟呈现)。模态在可见时,呈现为附加到 <body> 元素。<b-modal> 组件不会影响布局,因为它们在 DOM 位置呈现为占位符注释节点 (<!---->)。由于传送过程,可能需要两个或更多 $nextTick 才能将内容的更改呈现到目标中。

模态框可以在文档中就地呈现(即 <b-modal> 组件在文档中的位置)通过将 static 属性设置为 true。请注意,即使模态框在 statictrue 时不可见/未显示,模态框的内容也会在 DOM 中呈现。要使 static 模态框延迟呈现,还要将 lazy 属性设置为 true。然后,模态框仅在可见时才会出现在文档中。请注意,在 static 模式下,<b-modal> 组件的位置可能会影响文档和模态框的布局。

如果属性 static 不是 true(非静态模态框始终延迟呈现),则 lazy 属性将不起作用。

样式、选项和自定义

模态框有三种可选大小,可通过属性 size 获得。这些大小在特定断点处启动,以避免在较窄的视口中出现水平滚动条。有效的可选大小为 smlgxl

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

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

<!-- b-modal-sizes.vue -->

属性 size 将大小映射到 .modal-<size> 类。

滚动较长的内容

当模态框对于用户的视口或设备来说变得太长时,它们会独立于页面本身滚动。尝试下面的演示,看看我们的意思。

<div>
  <b-button v-b-modal.modal-tall>Launch overflowing modal</b-button>

  <b-modal id="modal-tall" title="Overflowing Content">
    <p class="my-4" v-for="i in 20" :key="i">
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
      in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
    </p>
  </b-modal>
</div>

<!-- b-modal-scroll-overflow.vue -->

您还可以创建一个可滚动模态框,允许滚动模态框主体,方法是将属性 scrollable 设置为 true

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

  <b-modal id="modal-scrollable" scrollable title="Scrollable Content">
    <p class="my-4" v-for="i in 20" :key="i">
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
      in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
    </p>
  </b-modal>
</div>

<!-- b-modal-scrollable-content.vue -->

垂直居中模态框

通过设置 centered 属性,在视口中垂直居中模态框。

<div>
  <b-button v-b-modal.modal-center>Launch centered modal</b-button>

  <b-modal id="modal-center" centered title="BootstrapVue">
    <p class="my-4">Vertically centered modal!</p>
  </b-modal>
</div>

<!-- b-modal-center-vertically.vue -->

随意将垂直 centeredscrollable 混合使用。

变体

通过设置 header-bg-variantheader-text-variantbody-bg-variantbody-text-variantfooter-bg-variantfooter-text-variant 属性来控制页眉、页脚和正文背景及文本变体。使用任何标准 Bootstrap 变体,例如 dangerwarninginfosuccessdarklight 等。

页眉底部边框和页脚顶部边框的变体可以通过 header-border-variantfooter-border-variant 属性分别进行控制。

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

    <b-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"
    >
      <b-container fluid>
        <b-row class="mb-1 text-center">
          <b-col cols="3"></b-col>
          <b-col>Background</b-col>
          <b-col>Text</b-col>
        </b-row>

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

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

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

      <template #modal-footer>
        <div class="w-100">
          <p class="float-left">Modal Footer Content</p>
          <b-button
            variant="primary"
            size="sm"
            class="float-right"
            @click="show=false"
          >
            Close
          </b-button>
        </div>
      </template>
    </b-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>

<!-- b-modal-variants.vue -->

你还可以通过 modal-classcontent-classheader-classbody-classfooter-class 属性分别将任意类应用于模态对话框容器、内容(模态窗口本身)、页眉、正文和页脚。这些属性接受字符串或字符串数组。

隐藏背景

通过设置 hide-backdrop 属性来隐藏模态的背景。

<div>
  <b-button v-b-modal.modal-no-backdrop>Open modal</b-button>

  <b-modal id="modal-no-backdrop" hide-backdrop content-class="shadow" title="BootstrapVue">
    <p class="my-2">
      We've added the utility class <code>'shadow'</code>
      to the modal content for added effect.
    </p>
  </b-modal>
</div>

<!-- modal-no-backdrop.vue -->

请注意,即使隐藏了背景,点击模态外部仍会关闭模态。你可以通过在 <b-modal> 上设置 no-close-on-backdrop 属性来禁用此行为。

禁用打开和关闭动画

若要禁用模态打开和关闭时的渐显过渡/动画,只需在 <b-modal> 组件上设置属性 no-fade

想要在默认页脚中使用更小或更大的按钮吗?只需将 button-size 属性设置为 'sm'(小按钮)或 'lg'(大按钮)即可。

<div>
  <b-button v-b-modal.modal-footer-sm>Small Footer Buttons</b-button>
  <b-button v-b-modal.modal-footer-lg>Large Footer Buttons</b-button>

  <b-modal id="modal-footer-sm" title="BootstrapVue" button-size="sm">
    <p class="my-2">This modal has small footer buttons</p>
  </b-modal>

  <b-modal id="modal-footer-lg" title="BootstrapVue" button-size="lg">
    <p class="my-2">This modal has large footer buttons</p>
  </b-modal>
</div>

<!-- modal-footer-btn-sizes.vue -->

如果你通过 modal-footer 插槽提供了自己的页脚,则属性 button-size 无效。

您可以通过编程方式禁用内置页脚按钮。

您可以通过分别将 cancel-disabledok-disabled 属性设置为 true,单独禁用 取消确定 按钮。将属性设置为 false 以重新启用按钮。

要同时禁用 取消确定 按钮,只需将 busy 属性设置为 true。将其设置为 false 以重新启用两个按钮。

使用插槽自定义渲染

<b-modal> 提供了几个命名插槽(其中一些是可选作用域),您可以使用它们来自定义模态各个部分的内容。

插槽 可选作用域 说明
default 模态的主内容
modal-title 放置在模态标题中的内容
modal-header 放置在页眉中的内容。替换整个页眉,包括关闭按钮
modal-footer 放置在页脚中的内容。替换整个页脚,包括按钮
modal-ok 放置在页脚确定按钮内部的内容
modal-cancel 放置在页脚取消按钮内部的内容
modal-header-close 放置在页眉关闭 (x) 按钮内部的内容

支持可选作用域的插槽可用的作用域是

方法或属性 说明
ok() 关闭模态并触发 okhide 事件,其中 bvModalEvent.trigger = 'ok'
cancel() 关闭模态并触发 cancelhide 事件,其中 bvModalEvent.trigger = 'cancel'
close() 关闭模态并触发 closehide 事件,其中 bvModalEvent.trigger = 'headerclose'
hide(trigger) 关闭模态并触发 hide 事件,其中 bvModalEvent.trigger = trigger(trigger 是可选的)
visible 模态的可视性状态。如果模态可见,则为 true,如果不可见,则为 false

使用自定义作用域插槽的模态示例

<template>
  <b-button @click="$bvModal.show('modal-scoped')">Open Modal</b-button>

  <b-modal id="modal-scoped">
    <template #modal-header="{ close }">
      <!-- Emulate built in modal header close button action -->
      <b-button size="sm" variant="outline-danger" @click="close()">
        Close Modal
      </b-button>
      <h5>Modal Header</h5>
    </template>

    <template #default="{ hide }">
      <p>Modal Body with button</p>
      <b-button @click="hide()">Hide Modal</b-button>
    </template>

    <template #modal-footer="{ ok, cancel, hide }">
      <b>Custom Footer</b>
      <!-- Emulate built in modal footer ok and cancel button actions -->
      <b-button size="sm" variant="success" @click="ok()">
        OK
      </b-button>
      <b-button size="sm" variant="danger" @click="cancel()">
        Cancel
      </b-button>
      <!-- Button with custom close trigger value -->
      <b-button size="sm" variant="outline-secondary" @click="hide('forget')">
        Forget it
      </b-button>
    </template>
  </b-modal>
</template>

<!-- b-modal-scoped-slots.vue -->

多个模态支持

与本机 Bootstrap v4 不同,BootstrapVue 支持同时打开多个模态。

要禁用特定模态的堆叠,只需在 <b-modal> 组件上设置属性 no-stacking。这将在显示另一个模态之前隐藏模态。

<div>
  <b-button v-b-modal.modal-multi-1>Open First Modal</b-button>

  <b-modal id="modal-multi-1" size="lg" title="First Modal" ok-only no-stacking>
    <p class="my-2">First Modal</p>
    <b-button v-b-modal.modal-multi-2>Open Second Modal</b-button>
  </b-modal>

  <b-modal id="modal-multi-2" title="Second Modal" ok-only>
    <p class="my-2">Second Modal</p>
    <b-button v-b-modal.modal-multi-3 size="sm">Open Third Modal</b-button>
  </b-modal>

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

<!-- b-modal-multiple.vue -->

备注

  • 避免将 <b-modal> 嵌套在另一个 <b-modal> 内部,因为它可能会“受限”于父模态对话框的边界(尤其是在使用静态模态时)。
  • 对于打开的每个模态,不透明背景会逐渐变暗。这是预期行为,因为每个背景都会在其他模态和背景之上打开。

BootstrapVue 在公开的 this.$bvModal 对象上提供了一些内置消息框方法。这些方法提供了一种生成简单的确定和确认样式模态消息的方式,无需在页面中明确放置 <b-modal> 组件,即可在应用程序中的任何位置生成此类消息。

方法 说明
this.$bvModal.msgBoxOk(message, options) 使用 message 作为内容和一个确定按钮打开模态
this.$bvModal.msgBoxConfirm(message, options) 使用 message 作为内容以及取消和确定按钮打开模态

options 参数是一个可选配置对象,用于添加标题和设置消息框模态的样式。对象属性对应于 <b-modal> 属性,但采用 camelCase 格式,而不是 kebab-case 格式。

这两种方法都返回一个 Promise(IE 11 和更早版本的浏览器支持需要一个 polyfill),当模态隐藏时,该 Promise 会解析为一个值。.msgBoxOk() 始终解析为值 true,而 .msgBoxConfirm() 解析为 true(按下了确定按钮)、false(按下了取消按钮)或 null(如果通过点击背景、按下 Esc 或其他方式关闭了模态)。

如果未提供 message,则这两种方法都会立即返回,值为 undefined

你可以使用 .then(..).catch(...) 或异步 await 代码样式(异步 await 需要现代浏览器或转换器)。

确定消息框

确定消息框示例

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

<script>
  export default {
    data() {
      return {
        boxOne: '',
        boxTwo: ''
      }
    },
    methods: {
      showMsgBoxOne() {
        this.boxOne = ''
        this.$bvModal.msgBoxOk('Action completed')
          .then(value => {
            this.boxOne = value
          })
          .catch(err => {
            // An error occurred
          })
      },
      showMsgBoxTwo() {
        this.boxTwo = ''
        this.$bvModal.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>

<!-- b-modal-msg-box-ok.vue -->

确认消息框

确认消息框示例

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

<script>
  export default {
    data() {
      return {
        boxOne: '',
        boxTwo: ''
      }
    },
    methods: {
      showMsgBoxOne() {
        this.boxOne = ''
        this.$bvModal.msgBoxConfirm('Are you sure?')
          .then(value => {
            this.boxOne = value
          })
          .catch(err => {
            // An error occurred
          })
      },
      showMsgBoxTwo() {
        this.boxTwo = ''
        this.$bvModal.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>

<!-- b-modal-msg-box-confirm.vue -->

消息框注释

  • 仅在使用完整 BootstrapVue 插件或 ModalPlugin 插件时,才可以使用 this.$bvModal 注入。如果仅导入 b-modal 组件,则无法使用它。若要仅导入注入,请使用 BVModalPlugin 插件。
  • 为每个 Vue 虚拟机(即每个实例化组件)创建一个新的 $bvModal 注入(混合),并且无法通过直接访问 Vue.prototype 来使用它,因为它需要访问实例的 this$root 上下文。
  • 消息框需要浏览器中的 Promise 支持。如果将应用定位到较旧的浏览器(例如 IE 11),请包含提供 Promise 支持的 polyfill。如果未检测到 Promise 支持,则消息框方法将立即返回 undefined
  • 消息框是 <b-modal> 组件的扩展,因此支持大多数 <b-modal> 属性(使用 camelCase 格式),但以下属性除外:lazystaticbusyvisiblenoStackingokOnlyokDisabledcancelDisabled
  • 如果在选项中提供 title(或 titleHtml),则不会显示标题。
  • 如果在选项中提供了 title(或 titleHtml),则默认情况下不会显示标题关闭按钮。你可以通过在选项中设置 hideHeaderClose: false 来启用标题关闭按钮。
  • 如果消息框在隐藏之前关闭/销毁,则会抛出错误(承诺拒绝)。始终包含 .catch(errHandler) 拒绝处理程序,即使使用异步 await 样式代码也是如此。
  • 在使用 Vue 路由器(或类似工具)时,如果在模态隐藏之前路由发生更改,消息框将关闭并拒绝。如果你希望在路由更改时消息框保持打开状态,请使用 this.$root.$bvModal 而不是 this.$bvModal
  • 无法在服务器端渲染 (SSR) 期间生成消息框。
  • 消息框 message 目前不支持 HTML 字符串,但是,你可以将 VNodes数组作为 message 传递,以便对标记进行细粒度控制。你可以使用 Vue 的 this.$createElement 方法生成 VNodes。还可以对模态标题(通过将 VNodes 传递给 title 选项)、确定按钮文本(通过 okTitle 选项)和取消按钮文本(通过 cancelTitle 选项)执行此操作。

消息框高级用法

在使用 this.$bvModal.msgBoxOk(...)this.$bvModal.msgBoxConfirm(...) 方法生成模态时,你可能希望模态内容不仅仅是字符串消息。如上文 消息框注释 部分所述,你可以将 VNodes 的数组作为消息和标题传递,以获得更复杂的内容。

使用 Vue 的 this.$createElement 方法生成 VNodes。

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

<script>
  export default {
    methods: {
      showMsgOk() {
        const h = this.$createElement
        // Using HTML string
        const titleVNode = h('div', { domProps: { innerHTML: 'Title from <i>HTML<i> string' } })
        // More complex structure
        const messageVNode = h('div', { class: ['foobar'] }, [
          h('p', { class: ['text-center'] }, [
            ' Flashy ',
            h('strong', 'msgBoxOk'),
            ' message ',
          ]),
          h('p', { class: ['text-center'] }, [h('b-spinner')]),
          h('b-img', {
            props: {
              src: 'https://picsum.photos/id/20/250/250',
              thumbnail: true,
              center: true,
              fluid: true, rounded: 'circle'
            }
          })
        ])
        // We must pass the generated VNodes as arrays
        this.$bvModal.msgBoxOk([messageVNode], {
          title: [titleVNode],
          buttonSize: 'sm',
          centered: true, size: 'sm'
        })
      }
    }
  }
</script>

<!-- modal-msg-box-advanced.vue -->

通过 $root 事件侦听模态更改

要侦听任何模态打开,请使用

export default {
  mounted() {
    this.$root.$on('bv::modal::show', (bvEvent, modalId) => {
      console.log('Modal is about to be shown', bvEvent, modalId)
    })
  }
}

有关所发送事件的完整列表,请参阅本说明文档的 事件 部分。

辅助功能

<b-modal> 提供了多种辅助功能,包括自动对焦、返回焦点、键盘(制表符)焦点包含和自动 aria-* 属性。

注意:此组件的动画效果取决于 prefers-reduced-motion 媒体查询。有关其他详细信息,请参阅 辅助功能说明文档的减少运动部分

在大多数情况下,aria-labelledbyaria-describedby 属性将自动出现在模态上。

  • 如果你隐藏了标题、提供了自己的标题或未提供模态标题,则 aria-labelledby 属性不会出现。建议为模态提供标题(使用内置标题时)。你可以隐藏标题标题,但仍可以通过设置 title-sr-only 属性使其对屏幕阅读器可用。如果没有标题,你可以通过将字符串传递给 aria-label 属性来为模态提供标签。
  • aria-describedby 属性始终指向模态框的主体内容。
  • 如果 aria-label 属性被指定为字符串值,则 aria-labelledby 属性将不会被渲染,即使您的模态框具有标题/页眉。

aria-labeltitle-sr-only 属性在 v2.0.0-rc.27 版本中添加。

打开时自动对焦

<b-modal> 在打开时会自动对焦模态框容器

您可以通过监听 <b-modal> shown 事件,并调用元素的 focus() 方法,预先对焦 <b-modal> 中的元素。如果 <b-modal> 中的元素已经获得焦点,<b-modal> 将不会尝试自动对焦。

<b-modal @shown="focusMyElement">
  <div>
    <b-button>I Don't Have Focus</b-button>
  </div>

  <div>
    <b-form-input></b-form-input>
  </div>

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

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

或者,如果您使用 b-form-* 表单控件,则可以使用 autofocus 属性在模态框打开时自动对焦表单控件。请注意,如果在不设置 lazy 属性的情况下使用 static 属性,autofocus 属性将无法与 b-modal 一起使用,因为 autofocusb-form-* 控件挂载到 DOM 中时发生。

如果您想自动对焦内置模态框按钮之一(okcancel 或页眉 close 按钮),您可以将 auto-focus-button 属性设置为 'ok''cancel''close' 中的一个值,如果 <b-modal> 存在指定的按钮,它将对焦该按钮。此功能也适用于模态框消息框。

注意:出于可访问性原因,不建议自动对焦模态框内的输入或控件,因为屏幕阅读器用户将不知道输入的上下文(可能不会说出模态框的播报)。最好让 <b-modal> 对焦模态框的容器,允许向用户播报模态框信息,然后允许用户切换到输入。

返回焦点到触发元素

出于可访问性原因,当模态关闭时,最好将焦点返回到触发模态打开的元素。

<b-modal> 将尝试自动确定模态打开之前哪个元素具有焦点,并在模态隐藏后尽可能将焦点返回到该元素。但是,提供了多种方法和选项,允许您指定模态隐藏后返回焦点的元素。

通过 return-focus 属性指定返回焦点元素

您还可以通过将 return-focus 属性设置为以下之一来指定模态关闭后返回焦点的元素

  • CSS 查询选择器字符串(或以 # 为前缀的元素 ID)
  • 组件引用(安装在可聚焦元素上,例如 <b-button>
  • 对可聚焦 DOM 元素的引用

如果传入的元素不可聚焦,则浏览器将确定具有焦点的内容(通常是 <body>,这是不可取的)

当您使用 <b-modal> 方法 show()hide()v-model 属性时,此返回焦点的方法非常方便。请注意,此属性优先于指定返回焦点元素的其他方法。

自动返回焦点

当通过元素上的 v-b-modal 指令打开 <b-modal> 时,焦点将自动返回到此元素,当 <b-modal> 关闭时,除非已通过 return-focus 属性指定了元素。

通过事件指定返回焦点

使用 bv::show::modal 事件(在 $root 上发出)时,您可以指定第二个参数,即返回焦点的元素。此参数接受与 return-focus 属性相同的类型。

this.$root.$emit('bv::show::modal', 'modal-1', '#focusThisOnClose')

提示:如果使用单击事件(或类似事件)触发模态打开,请传递事件的 target 属性

<div>
  <b-button @click="$root.$emit('bv::show::modal', 'modal-1', $event.target)">Open Modal</b-button>
</div>

注意:如果 <b-modal> 设置了 return-focus 属性,则将忽略通过事件指定的元素。

键盘导航

<b-modal> 中通过元素使用 tab 键时,如果焦点尝试离开模态进入文档,它将被带回模态。

避免将模态内元素的 tabindex 设置为 0-1 以外的任何值。这样做会使依赖辅助技术来导航和操作页面内容的人们难以操作,并且可能导致一些元素无法通过键盘导航访问。

如果模态外部的某些元素需要可聚焦(例如,对于 TinyMCE),你可以将它们作为 CSS 选择器添加到 ignore-enforce-focus-selector 属性中 2.4.0+,例如:

<b-modal
  id="some-modal-id"
  title="Modal with TinyMCE Editor"
  ignore-enforce-focus-selector=".tox-tinymce-aux, .moxman-window, .tam-assetmanager-root"
>
  <!-- Modal content with TinyMCE editor here -->
</b-modal>

在某些情况下,你可能需要完全禁用强制焦点功能。你可以通过设置属性 no-enforce-focus 来执行此操作,尽管出于可访问性原因,强烈不建议这样做。

v-b-modal 指令可访问性

关于 v-b-modal 指令可访问性的说明

  • 如果元素不是 <button>(或呈现 <button> 的组件),ARIA role 将设置为 button,并且会添加 EnterSpace 的 keydown 事件侦听器,以及一个 click 侦听器。
  • 如果元素不是 <button><a>(或呈现任一元素的组件),则会将 tabindex0 添加到元素中以确保可访问性,除非已经设置了 tabindex

组件参考

<b-modal>

属性

所有属性默认值均可 全局配置

属性
(点击按升序排列)
类型
(点击按升序排列)
默认值
说明
aria-label
字符串明确为模态框提供“aria-label”属性。当模态框没有标题时应设置。当未设置时,“aria-labelledby”将指向模态框的标题
auto-focus-button
v2.0.0+
字符串null指定模态框打开后要聚焦哪个内置按钮:“ok”、“cancel”或“close”
body-bg-variant
字符串将 Bootstrap 主题颜色变体之一应用于主体背景
body-class
ArrayObjectString要应用于“‘.modal-body’”包装器元素的 CSS 类(或类)
body-text-variant
字符串将 Bootstrap 主题颜色变体之一应用于主体文本
busy
布尔值false将内置的默认页脚确定和取消按钮置于禁用状态
button-size
字符串内置页脚按钮的大小:“sm”、“md”(默认)或“lg”
cancel-disabled
布尔值false将默认页脚取消按钮置于禁用状态
cancel-title
字符串'Cancel'要置于默认页脚取消按钮中的文本字符串
cancel-title-html
谨慎使用
字符串要置于默认页脚取消按钮中的 HTML 字符串
cancel-variant
字符串'secondary'要应用于默认页脚取消按钮的按钮颜色主题变体
centered
布尔值false在视口中垂直居中模态框
content-class
ArrayObjectString要应用于“‘.modal-content’”包装器元素的 CSS 类(或类)
dialog-class
ArrayObjectString要应用于“‘.modal-dialog’”包装器元素的 CSS 类(或类)
footer-bg-variant
字符串将 Bootstrap 主题颜色变体之一应用于页脚背景
footer-border-variant
字符串将 Bootstrap 主题颜色变体之一应用于页脚边框
footer-class
ArrayObjectString应用于 '.modal-footer' 包装元素的 CSS 类(或类)
footer-tag
v2.22.0+
字符串'footer'指定要呈现的 HTML 标记,而不是页脚的默认标记
footer-text-variant
字符串将 Bootstrap 主题颜色变体之一应用于页脚文本
header-bg-variant
字符串将 Bootstrap 主题颜色变体之一应用于页眉背景
header-border-variant
字符串将 Bootstrap 主题颜色变体之一应用于页眉边框
header-class
ArrayObjectString应用于 '.modal-header' 包装元素的 CSS 类(或类)
header-close-content
v2.3.0+
字符串'&times;'页眉关闭按钮的内容
header-close-label
字符串'关闭'页眉关闭按钮上 'aria-label' 的值
header-close-variant
字符串应用于页眉关闭按钮的文本主题颜色变体
header-tag
v2.22.0+
字符串'header'指定要呈现的 HTML 标记,而不是页脚的默认标记
header-text-variant
字符串将 Bootstrap 主题颜色变体之一应用于页眉文本
hide-backdrop
布尔值false禁用模态背景的呈现
hide-footer
布尔值false禁用模态页脚的呈现
hide-header
布尔值false禁用模态页眉的呈现
hide-header-close
布尔值false禁用模态页眉关闭按钮的呈现
id
字符串用于设置呈现内容上的 `id` 属性,并用作根据需要生成任何其他元素 ID 的基础
ignore-enforce-focus-selector
v2.4.0+
ArrayString忽略由 CSS 选择器指定的强制焦点例程中的某些元素
lazy
布尔值false当模态具有 `static` 属性集时,以延迟方式呈现模态内容
modal-class
ArrayObjectString应用于 '.modal' 包装元素的 CSS 类(或类)
no-close-on-backdrop
布尔值false禁用通过单击背景关闭模态的功能
no-close-on-esc
布尔值false禁用通过按 ESC 关闭模态的功能
no-enforce-focus
布尔值false禁用在模态内保持焦点的强制焦点例程
no-fade
布尔值false当设置为 `true` 时,禁用组件上的淡入淡出动画/过渡
no-stacking
布尔值false防止其他模态堆叠在此模态之上
ok-disabled
布尔值false将默认页脚确定按钮置于禁用状态
ok-only
布尔值false禁用默认页脚取消按钮的渲染
ok-title
字符串'确定'放置在默认页脚确定按钮中的文本字符串
ok-title-html
谨慎使用
字符串放置在默认页脚确定按钮中的 HTML 字符串
ok-variant
字符串'primary'应用于默认页脚确定按钮的按钮颜色主题变体
return-focus
HTMLElementObjectString在模态关闭时返回焦点的 HTML 元素引用、CSS 选择器或组件引用。未设置时,将焦点返回到模态打开前最后具有焦点的元素
scrollable
布尔值false启用模态正文的滚动
size
字符串'md'设置模态宽度的尺寸。'sm'、'md'(默认)、'lg' 或 'xl'
static
布尔值false在 DOM 中就地渲染组件的内容,而不是将其传送以追加到 body 元素
title
字符串放置在标题中的文本内容
title-class
ArrayObjectString应用于标题的 CSS 类(或类)
title-html
谨慎使用
字符串放置在标题中的 HTML 字符串内容
title-sr-only
布尔值false用 '.sr-only' 包装器包装标题
title-tag
字符串'h5'指定要渲染的 HTML 标记,而不是标题的默认标记
visible
v-model
布尔值false模态的当前可见性状态

注意:支持 HTML 字符串 (*-html) 的属性在传递原始用户提供的值时可能容易受到 跨站点脚本 (XSS) 攻击 。您必须先正确 清理 用户输入!

v-model

属性
事件
visiblechange

插槽

名称
范围
说明
default 模态框正文内容。可选范围
模态框背景 模态框背景内容
modal-cancel 模态框取消按钮内容
modal-footer 模态框页脚内容。还会移除默认的确定和取消按钮。可选范围
modal-header 整个模态框标题容器内容。还会移除右上角的 X 关闭按钮。可选范围
modal-header-close 模态框标题关闭按钮内容。如果使用了 `modal-header` 插槽,则不会显示此插槽
modal-ok 模态框确定按钮内容
modal-title 模态框标题。如果使用了 `modal-header` 插槽,则不会显示此插槽。可选范围

事件

事件
(点击按升序排列)
参数
说明
bv::modal::hidden
  1. bvModalEvent - BvModalEvent 对象
  2. modalId - 模态框 ID
当模态框隐藏时在 `$root` 上发出
bv::modal::hide
  1. bvModalEvent - BvModalEvent 对象。调用 `bvModalEvent.preventDefault()` 取消隐藏
  2. modalId - 模态框 ID
当模态框即将隐藏时在 `$root` 上发出。可取消(只要模态框不是强制隐藏的)
bv::modal::show
  1. bvModalEvent - BvModalEvent 对象。调用 `bvModalEvent.preventDefault()` 取消显示
  2. modalId - 模态框 ID
当模态框即将显示时在 `$root` 上发出。可取消
bv::modal::shown
  1. bvModalEvent - BvModalEvent 对象
  2. modalId - 模态框 ID
当模态框显示时在 `$root` 上发出
cancel
  1. bvModalEvent - BvModalEvent 对象。调用 `bvModalEvent.preventDefault()` 取消隐藏
当按下默认取消按钮时,模态框隐藏之前。可取消
change
  1. isVisible - 模态框的可见性状态。如果模态框可见,则为 `true`;如果不可见,则为 `false`
新的模态框可见性状态。用于更新 v-model
close
  1. bvModalEvent - BvModalEvent 对象。调用 `bvModalEvent.preventDefault()` 取消隐藏
当按下默认标题关闭按钮时,模态框隐藏之前。可取消
hidden
  1. bvModalEvent - BvModalEvent 对象
模态框隐藏后始终发出
hide
  1. bvModalEvent - BvModalEvent 对象。检查 `bvModalEvent.trigger` 以找出触发隐藏的动作。调用 `bvModalEvent.preventDefault()` 取消隐藏
模态框隐藏之前始终触发。可取消(只要模态框不是强制隐藏的)
ok
  1. bvModalEvent - BvModalEvent 对象。调用 `bvModalEvent.preventDefault()` 取消隐藏
当按下默认的确定按钮时,在模态框隐藏之前触发。可取消
show
  1. bvModalEvent - BvModalEvent 对象。调用 `bvModalEvent.preventDefault()` 取消显示
模态框显示之前始终触发。可取消
shown
  1. bvModalEvent - BvModalEvent 对象
模态框显示时始终触发

$root 事件侦听器

可以通过在 $root 上触发以下事件来控制 <b-modal>

事件
参数
说明
bv::hide::modal

modalId - 要隐藏的模态框的 ID

当在 `root` 上触发此事件时,隐藏具有指定 ID 的模态框
bv::show::modal

modalId - 要显示的模态框的 ID

elIDtoFocusOnClose - 指定元素引用或 CSS 选择器,以便在模态框关闭后返回焦点(可选)

当在 `$root` 上触发此事件时,显示具有指定 ID 的模态框
bv::toggle::modal

modalId - 要切换可见性的模态框的 ID

elIDtoFocusOnClose - 指定元素引用或 CSS 选择器,以便在模态框关闭后返回焦点(可选)

根据其 ID 切换模态框的可见性

导入单个组件

可以通过以下命名导出将单个组件导入到项目中

组件
命名导出
导入路径
<b-modal>BModalbootstrap-vue

示例

import { BModal } from 'bootstrap-vue'
Vue.component('b-modal', BModal)

导入单个指令

可以通过以下命名导出将单个指令导入到项目中

指令
命名导出
导入路径
v-b-modalVBModalbootstrap-vue

示例

import { VBModal } from 'bootstrap-vue'
// Note: Vue automatically prefixes the directive name with 'v-'
Vue.directive('b-modal', VBModal)

作为 Vue.js 插件导入

此插件包含上述所有列出的单个组件和指令。插件还包括任何组件别名。

命名导出
导入路径
ModalPluginbootstrap-vue

此插件还自动包含以下插件

  • BVModalPlugin

示例

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