当前位置:首页 > VUE

vue手动实现dialog

2026-02-10 19:10:54VUE

手动实现 Vue Dialog 组件

在 Vue 中手动实现 Dialog 组件可以通过组合式 API 或选项式 API 完成,以下是核心实现思路和代码示例:

组件基础结构

创建 Dialog.vue 文件,包含模板、样式和逻辑:

<template>
  <div class="dialog-overlay" v-if="visible" @click.self="handleClose">
    <div class="dialog-container">
      <div class="dialog-header">
        <slot name="header">
          <h3>{{ title }}</h3>
        </slot>
        <button class="close-btn" @click="handleClose">×</button>
      </div>
      <div class="dialog-body">
        <slot></slot>
      </div>
      <div class="dialog-footer">
        <slot name="footer">
          <button @click="handleClose">取消</button>
          <button @click="handleConfirm">确认</button>
        </slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '提示'
    }
  },
  emits: ['update:visible', 'confirm', 'close'],
  methods: {
    handleClose() {
      this.$emit('update:visible', false);
      this.$emit('close');
    },
    handleConfirm() {
      this.$emit('confirm');
      this.handleClose();
    }
  }
};
</script>

<style scoped>
.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.dialog-container {
  background: white;
  border-radius: 4px;
  min-width: 300px;
  max-width: 80%;
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  padding: 16px;
  border-bottom: 1px solid #eee;
}

.dialog-body {
  padding: 16px;
}

.dialog-footer {
  padding: 16px;
  border-top: 1px solid #eee;
  text-align: right;
}

.close-btn {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
}
</style>

使用组件

在父组件中通过 v-model 控制 Dialog 显示/隐藏:

vue手动实现dialog

<template>
  <button @click="showDialog = true">打开弹窗</button>
  <Dialog v-model:visible="showDialog" @confirm="handleConfirm">
    <template #header>
      自定义标题
    </template>
    这里是弹窗内容
    <template #footer>
      <button @click="showDialog = false">自定义按钮</button>
    </template>
  </Dialog>
</template>

<script>
import Dialog from './Dialog.vue';

export default {
  components: { Dialog },
  data() {
    return {
      showDialog: false
    };
  },
  methods: {
    handleConfirm() {
      console.log('确认操作');
    }
  }
};
</script>

进阶功能扩展

动画效果 添加过渡动画增强用户体验:

<template>
  <transition name="fade">
    <div class="dialog-overlay" v-if="visible" @click.self="handleClose">
      <transition name="scale">
        <div class="dialog-container">
          <!-- 内容不变 -->
        </div>
      </transition>
    </div>
  </transition>
</template>

<style scoped>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}

.scale-enter-active, .scale-leave-active {
  transition: transform 0.3s;
}
.scale-enter-from, .scale-leave-to {
  transform: scale(0.9);
}
</style>

全局调用 通过 Vue 插件方式实现全局调用:

vue手动实现dialog

// dialogPlugin.js
import Dialog from './Dialog.vue';

export default {
  install(app) {
    const showDialog = (options) => {
      const mountNode = document.createElement('div');
      document.body.appendChild(mountNode);

      const instance = createApp({
        render() {
          return h(Dialog, {
            visible: true,
            ...options,
            onClose: () => {
              instance.unmount();
              document.body.removeChild(mountNode);
              options.onClose?.();
            }
          });
        }
      });

      instance.mount(mountNode);
    };

    app.config.globalProperties.$dialog = showDialog;
  }
};

在 main.js 中安装插件:

import dialogPlugin from './dialogPlugin';
app.use(dialogPlugin);

组件内使用:

this.$dialog({
  title: '全局弹窗',
  content: '通过插件调用',
  onConfirm: () => console.log('全局确认')
});

标签: vuedialog
分享给朋友:

相关文章

vue实现冰墩墩

vue实现冰墩墩

使用 Vue 实现冰墩墩动画 通过 Vue 的动画特性和 SVG 技术,可以动态渲染冰墩墩的形象。以下是具体实现方法: 准备 SVG 素材 冰墩墩的形象通常由多个 SVG 路径组成,包括身体轮廓…

vue实现倒计时抢券

vue实现倒计时抢券

Vue 实现倒计时抢券功能 核心逻辑 倒计时抢券功能需要结合时间计算、状态管理和界面交互。通过 Vue 的响应式特性和生命周期钩子,可以高效实现这一需求。 实现步骤 1. 数据准备 在 Vue 组…

vue实现cs

vue实现cs

Vue 实现 CS(Client-Side)渲染的常见方法 Vue.js 是一个用于构建用户界面的渐进式框架,默认采用客户端渲染(CSR)。以下是几种常见的实现方式: 使用 Vue CLI 创建项…

vue实现换行

vue实现换行

Vue 中实现换行的几种方法 在 Vue 中实现换行可以通过多种方式,具体取决于使用场景和需求。以下是常见的几种方法: 使用 HTML 的 <br> 标签 在模板中直接使用 <br…

vue实现长按

vue实现长按

Vue 实现长按功能的方法 在 Vue 中实现长按功能可以通过原生事件监听或自定义指令完成。以下是几种常见实现方式: 使用原生事件监听 通过 @mousedown 和 @mouseup 或 @tou…

vue 实现排序

vue 实现排序

Vue 实现排序的方法 使用计算属性实现排序 通过计算属性对数组进行排序,可以保持原始数据不变。示例代码展示了如何对列表按名称升序排序: <template> <div>…