VEUI

VEUI on GitHub
Play!中文

Dialog

Examples

Sizes and fullscreen

Available size/dimensional variants for the ui prop: s / m / narrow / medium / wide / auto.

s / m are used to specify size for internal content and will be inherited by components inside the dialog. While narrow / medium / wide / fullscreen / auto are used to specify the dimension of the dialog itself, thus can be used together with s / m.

Edit this demo on GitHubEdit
<template>
<article>
  <veui-button
    class="button"
    @click="openDialog('s')"
  >
    s
  </veui-button>
  <veui-button
    class="button"
    @click="openDialog('m')"
  >
    m
  </veui-button>
  <veui-button
    class="button"
    @click="openDialog('narrow')"
  >
    narrow
  </veui-button>
  <veui-button
    class="button"
    @click="openDialog('medium')"
  >
    medium
  </veui-button>
  <veui-button
    class="button"
    @click="openDialog('wide')"
  >
    wide
  </veui-button>
  <veui-button
    class="button"
    @click="openDialog('fullscreen')"
  >
    fullscreen
  </veui-button>
  <veui-button
    class="button"
    @click="openDialog('auto')"
  >
    auto
  </veui-button>
  <veui-dialog
    title="System"
    :ui="ui"
    :open.sync="open"
  >
    <section>Current UI: "{{ ui }}"</section>
    <section v-if="ui === 's' || ui === 'm'">
      <veui-button class="button">
        Button size: {{ ui }}
      </veui-button>
      <veui-switch>{{ ui }}</veui-switch>
    </section>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, Switch } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button,
    'veui-switch': Switch
  },
  data () {
    return {
      open: false,
      ui: null
    }
  },
  methods: {
    openDialog (size) {
      this.ui = size
      this.open = true
    }
  }
}
</script>

<style lang="less" scoped>
.button {
  margin-right: 20px;
}
</style>
Edit this demo on GitHubEdit
<template>
<article>
  <veui-button
    class="button"
    @click="modalOpen = true"
  >
    Modal
  </veui-button>
  <veui-button
    class="button"
    @click="nonModalOpen = true"
  >
    Non-modal
  </veui-button>
  <veui-dialog
    title="System"
    :open.sync="modalOpen"
    @ok="handleModalClose(true)"
    @cancel="handleModalClose"
  >
    Do you want to refresh the page?
  </veui-dialog>
  <veui-dialog
    title="System"
    :open.sync="nonModalOpen"
    :modal="false"
    @ok="handleModalClose(true)"
    @cancel="handleModalClose"
  >
    Do you want to refresh the page?
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      modalOpen: false,
      nonModalOpen: false
    }
  },
  methods: {
    handleModalClose (ok) {
      this.modalOpen = false
      if (ok) {
        location.reload()
      }
    },
    handleNonModalClose (ok) {
      this.nonModalOpen = false
      if (ok) {
        location.reload()
      }
    }
  }
}
</script>

<style lang="less" scoped>
.button {
  margin-right: 20px;
}
</style>

Custom content

Edit this demo on GitHubEdit
<template>
<article>
  <veui-button
    class="button"
    @click="simpleOpen = true"
  >
    Title & content
  </veui-button>
  <veui-dialog
    :open.sync="simpleOpen"
    title="Customized Title & Content"
    @ok="simpleOpen = false"
    @cancel="simpleOpen = false"
  >
    Customized content via <code>&lt;slot&gt;</code>.
  </veui-dialog>

  <veui-button
    class="button"
    @click="titleIconOpen = true"
  >
    Icon in Title
  </veui-button>
  <veui-dialog
    :open.sync="titleIconOpen"
    @ok="titleIconOpen = false"
    @cancel="titleIconOpen = false"
  >
    <template #title>
      Title with Icon <veui-icon name="flag"/>
    </template>
    Customized content via <code>&lt;slot&gt;</code>.
  </veui-dialog>

  <veui-button
    class="button"
    @click="footOpen = true"
  >
    Foot
  </veui-button>
  <veui-dialog
    :open.sync="footOpen"
    title="Customized Foot"
  >
    Customized content via <code>&lt;slot&gt;</code>.
    <template #foot="{ close }">
      <veui-button
        ui="s primary"
        @click="close('ok')"
      >
        Close
      </veui-button>
    </template>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, Icon } from 'veui'
import 'veui-theme-dls-icons/flag'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button,
    'veui-icon': Icon
  },
  data () {
    return {
      simpleOpen: false,
      titleIconOpen: false,
      footOpen: false
    }
  }
}
</script>

<style lang="less" scoped>
.button {
  margin-right: 20px;
}
</style>

Async support

When you want a unified process to handle all user interactions that might trigger the dialog to be closed, you can leverage the before-close function prop. No matter the close behavior is about to be triggered by clicking “OK”/“Cancel” buttons, the close button or pressing esc, before-close will always take over the following process. If the logic is relatively simple, you can manipulate open prop directly to close the dialog.

Edit this demo on GitHubEdit
<template>
<article>
  <veui-button
    class="button"
    :disabled="submitting"
    @click="submitOpen = true"
  >
    Submit
  </veui-button>
  <veui-button
    class="button"
    :disabled="saving"
    @click="saveOpen = true"
  >
    Save
  </veui-button>
  <veui-dialog
    title="System"
    :open.sync="submitOpen"
    :before-close="submit"
    :closable="false"
    :escapable="!submitting"
    :loading="submitting"
  >
    Confirm to create the issue?
  </veui-dialog>
  <veui-dialog
    title="System"
    :open.sync="saveOpen"
    :closable="false"
    :escapable="!submitting"
  >
    Confirm to save the post?
    <template #foot>
      <veui-button
        ui="primary"
        :loading="saving"
        @click="save('ok')"
      >
        OK
      </veui-button>
      <veui-button
        :disabled="saving"
        @click="save"
      >
        Cancel
      </veui-button>
    </template>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, toast } from 'veui'

function fakeRequest () {
  return new Promise(resolve =>
    setTimeout(() => {
      resolve(Math.random() < 0.5)
    }, 2000)
  )
}

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      submitOpen: false,
      saveOpen: false,
      submitting: false,
      saving: false
    }
  },
  methods: {
    submit (type) {
      if (type === 'ok') {
        this.submitting = true
        return fakeRequest().then(success => {
          this.submitting = false
          if (!success) {
            toast.error('Failed to create the issue. Please retry.')
            return false
          }
          toast.success('Issue created successfully!')
        })
      }
    },
    save (type) {
      if (type === 'ok') {
        this.saving = true
        return fakeRequest().then(success => {
          this.saving = false
          if (!success) {
            toast.error('Failed to save the post. Please retry.')
          } else {
            toast.success('Post saved successfully!')
            this.saveOpen = false
          }
        })
      }
      this.saveOpen = false
    }
  }
}
</script>

<style lang="less" scoped>
.button {
  margin-right: 20px;
}
</style>

Draggable

Edit this demo on GitHubEdit
<template>
<article>
  <veui-button @click="draggableOpen = true">
    Draggable
  </veui-button>
  <veui-dialog
    :open.sync="draggableOpen"
    title="Draggable Dialog"
    draggable
    @ok="draggableOpen = false"
    @cancel="draggableOpen = false"
  >
    This dialog is draggable.
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      draggableOpen: false
    }
  }
}
</script>

Stacking order

Open both dialogs and drag one of them to make them overlap a little bit. Then when you activate one dialog, it will be displayed on top of the other one.

Edit this demo on GitHubEdit
<template>
<article>
  <veui-button
    class="button"
    @click="aOpen = true"
  >
    Dialog A
  </veui-button>
  <veui-dialog
    :open.sync="aOpen"
    title="Dialog A"
    draggable
    :modal="false"
    @ok="aOpen = false"
    @cancel="aOpen = false"
  >
    The content of Dialog A.
  </veui-dialog>

  <veui-button
    class="button"
    @click="bOpen = true"
  >
    Dialog B
  </veui-button>
  <veui-dialog
    :open.sync="bOpen"
    title="Dialog B"
    draggable
    :modal="false"
    @ok="bOpen = false"
    @cancel="bOpen = false"
  >
    The content of Dialog B.
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button
  },
  data () {
    return {
      aOpen: false,
      bOpen: false
    }
  }
}
</script>

<style lang="less" scoped>
.button {
  margin-right: 20px;
}
</style>

Loading and disabled states

Edit this demo on GitHubEdit
<template>
<article>
  <veui-button @click="open = true">
    Open Dialog
  </veui-button>
  <veui-dialog
    :open.sync="open"
    title="Dialog State"
    :loading="loading"
    :disabled="disabled"
  >
    <veui-stack gap="m">
      <veui-checkbox v-model="loading">
        Loading
      </veui-checkbox>
      <veui-checkbox
        v-model="disabled"
        class="ml-3p"
      >
        Disabled
      </veui-checkbox>
    </veui-stack>
  </veui-dialog>
</article>
</template>

<script>
import { Dialog, Button, Stack, Checkbox } from 'veui'

export default {
  components: {
    'veui-dialog': Dialog,
    'veui-button': Button,
    'veui-stack': Stack,
    'veui-checkbox': Checkbox
  },
  data () {
    return {
      open: false,
      disabled: false,
      loading: false
    }
  }
}
</script>

API

Props

NameTypeDefaultDescription
uistring-

The preset style.

ValueDescription
sSmall content size (size of content and components, not the overall size of the dialog box).
mMedium content size (size of content and components, not the overall size of the dialog box).
narrowNarrow style.
mediumMedium style.
wideWide style.
fullscreenFullscreen style.
autoAdaptive size style.
modalbooleantrueWhether the dialog is modal. A modal dialog blocks the underlying content (cannot be clicked) and takes focus away (focus returns after the dialog is closed).
titlestring-The text for the dialog title. If the title slot is specified, it takes precedence over this prop.
openbooleanfalse

.sync

Whether the dialog box is displayed.

closablebooleantrueWhether to show the close button.
outside-closablebooleanfalseWhether to close the dialog when clicked outside.
draggablebooleanfalseWhether the dialog is draggable.
escapablebooleanfalseWhether pressing esc can close the dialog. This only takes effect when closable is true.
inlinebooleanfalseWhether to inline the dialog and occupy content space.
footlessbooleanfalseWhether to hide the default bottom bar.
loadingbooleanfalseWhether the dialog is in a loading state. When in a loading state, the OK button also enters a loading state and cannot be clicked.
disabledbooleanfalseWhether the dialog is in a disabled state. When in a disabled state, the OK button also enters a disabled state and cannot be clicked.
ok-labelstring-The text for the "OK" button.
cancel-labelstring-The text for the "Cancel" button.
prioritynumber-The stacking order of the dialog layer, refer to the Overlay component's priority prop.
before-closefunction(string): boolean=|Promise<boolean>-

Executed after the action that triggers the closing of the dialog box occurs, with a type of function(type: string): boolean=|Promise<boolean=>. By default, type can be 'ok'|'cancel'. The return value can be a boolean or a Promise that resolves to a boolean, used to handle situations where the dialog box closing state needs to be decided asynchronously. The dialog box will only be closed when the return value or resolved value is not false.

<veui-dialog :open.sync="dialogOpen" :before-close="submit">...</veui-dialog>
methods: {
  submit (type) {
    if (type === 'ok') {
      return axios.post('/item/create', {/* ... */})
        .then(({ id, error }) => {
          if (error) {
            this.showError(error)
            return false // Resolving `false` will prevent dialog box from closing.
          }
        })
    }
    // When resolved but not returning `false`, dialog box will be closed.
  },
  // ...
}
overlay-classstring | Object-The class name of the dialog layer root element, refer to the Overlay component's overlay-class prop.
overlay-stylestring | Array | Object-Refer to the Overlay component's overlay-style prop.

Slots

NameDescription
defaultContent area.
titleTitle area. If both the title prop and the title slot are specified, the latter takes precedence.
foot

Footer area. By default, the "OK" and "Cancel" buttons are displayed.

NameTypeDescription
closefunction(type: string): voidThe callback function that triggers the closing of the dialog box. type is the type of closing that will be passed to the before-close hook as a parameter, and the event with the same name will be triggered synchronously.

Events

NameDescription
okTriggered when the "OK" button is clicked or when the scope function close('ok') is called.
cancelTriggered when the "Cancel" button is clicked, when the close button is clicked, when the dialog box is closed by pressing esc, or when the scope function close('cancel') is called.
<value>Triggered when the scope function close(value) is called.
afteropenTriggered after the dialog box is opened. The content of the dialog box is rendered only after it is opened, so if there is logic that depends on the content being rendered, it should be executed after this event is triggered.
aftercloseTriggered after the dialog box is closed. If the style theme provides an exit animation, it will be triggered after the exit animation is complete.

Icons

NameDescription
closeClose.

CSS

NameTypeDefaultDescription
--dls-dialog-width<length>-

The width of the entire dialog box. Cannot be set at the same time as --dls-dialog-content-width.

--dls-dialog-content-width<length>-

The width of the content area of the dialog box. Cannot be set at the same time as --dls-dialog-width.

Edit this page on GitHubEdit
© Baidu, Inc. 2024