当前位置:首页 > VUE

vue自己实现dialog

2026-01-18 12:49:14VUE

实现自定义 Dialog 组件

封装基础 Dialog 组件 创建 Dialog.vue 文件,使用 v-model 控制显示状态,通过插槽支持内容自定义:

<template>
  <div class="dialog-mask" v-if="visible" @click.self="close">
    <div class="dialog-container">
      <div class="dialog-header">
        <slot name="header">{{ title }}</slot>
        <button @click="close">×</button>
      </div>
      <div class="dialog-body">
        <slot></slot>
      </div>
      <div class="dialog-footer">
        <slot name="footer">
          <button @click="close">取消</button>
          <button @click="$emit('confirm')">确定</button>
        </slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    visible: Boolean,
    title: String
  },
  methods: {
    close() {
      this.$emit('update:visible', false)
    }
  }
}
</script>

<style scoped>
.dialog-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}
.dialog-container {
  background: white;
  min-width: 300px;
  border-radius: 4px;
  overflow: hidden;
}
.dialog-header {
  padding: 16px;
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid #eee;
}
.dialog-body {
  padding: 24px 16px;
}
.dialog-footer {
  padding: 12px 16px;
  text-align: right;
  border-top: 1px solid #eee;
}
</style>

通过服务式调用 创建 dialog.js 服务文件实现动态调用:

import Vue from 'vue'

const DialogConstructor = Vue.extend(require('./Dialog.vue'))

function showDialog(options) {
  const instance = new DialogConstructor({
    propsData: options.props
  })

  if (options.parent) {
    instance.$mount(options.parent.appendChild(document.createElement('div')))
  } else {
    document.body.appendChild(instance.$mount().$el)
  }

  return {
    close: () => {
      instance.visible = false
      setTimeout(() => {
        instance.$destroy()
        instance.$el.remove()
      }, 300)
    }
  }
}

export default {
  install(Vue) {
    Vue.prototype.$dialog = showDialog
  }
}

全局注册使用main.js 中安装插件:

vue自己实现dialog

import Dialog from './plugins/dialog'
Vue.use(Dialog)

组件调用示例

<template>
  <button @click="show">打开弹窗</button>
</template>

<script>
export default {
  methods: {
    show() {
      this.$dialog({
        props: {
          visible: true,
          title: '提示'
        }
      })
    }
  }
}
</script>

模板调用示例

vue自己实现dialog

<Dialog v-model="visible" title="自定义标题">
  <template #header>替换标题</template>
  主体内容
  <template #footer>
    <button @click="visible = false">关闭</button>
  </template>
</Dialog>

动画效果增强 添加过渡动画需修改样式:

.dialog-mask {
  /* 原有样式 */
  opacity: 0;
  transition: opacity 0.3s;
}
.dialog-mask.v-enter-active, 
.dialog-mask.v-leave-active {
  opacity: 1;
}
.dialog-container {
  transform: translateY(-20px);
  transition: transform 0.3s;
}
.dialog-mask.v-enter-active .dialog-container,
.dialog-mask.v-leave-active .dialog-container {
  transform: translateY(0);
}

注意事项

  • 通过 z-index 控制层级关系
  • 防止背景滚动需添加 overflow: hiddenbody
  • 服务式调用需手动管理组件销毁
  • 可通过 provide/inject 实现深层嵌套内容控制

标签: vuedialog
分享给朋友:

相关文章

vue实现triger

vue实现triger

在Vue中实现触发器(trigger)功能通常涉及自定义事件或DOM事件触发。以下是几种常见场景的实现方法: 自定义事件触发 通过$emit方法触发父组件中监听的自定义事件: // 子组件 thi…

vue实现toast

vue实现toast

Vue 实现 Toast 的方法 使用第三方库(推荐) 对于快速实现 Toast 功能,推荐使用成熟的第三方库如 vue-toastification 或 vant 的 Toast 组件。 安装 v…

vue实现甘特图

vue实现甘特图

使用 Vue 实现甘特图 基于开源库(如 vue-ganttastic) 安装依赖库: npm install vue-ganttastic 示例代码: <template> &l…

vue实现左右拉伸

vue实现左右拉伸

实现左右拉伸布局的方法 使用CSS Flexbox布局 Flexbox可以轻松实现左右拉伸的效果。通过设置display: flex和flex-grow属性,可以让元素填充可用空间。 <div…

vue弹幕实现暂停

vue弹幕实现暂停

实现 Vue 弹幕暂停功能 监听播放状态 通过 v-model 或自定义事件绑定弹幕组件的播放状态,存储一个布尔值(如 isPlaying)控制播放与暂停。在弹幕滚动逻辑中根据该状态判断是否更新位置。…

vue实现树目录

vue实现树目录

Vue 实现树形目录 在 Vue 中实现树形目录可以通过递归组件或第三方库(如 element-ui 的 el-tree)完成。以下是两种常见实现方式: 递归组件实现 递归组件适合自定义程度高的树形…