当前位置:首页 > VUE

vue 实现弹窗组件

2026-01-16 21:57:52VUE

Vue 弹窗组件实现

基础弹窗组件结构

创建一个名为Modal.vue的文件,定义弹窗的基础结构和样式:

<template>
  <div class="modal-mask" v-show="visible" @click.self="close">
    <div class="modal-container">
      <div class="modal-header">
        <h3>{{ title }}</h3>
        <button @click="close">&times;</button>
      </div>
      <div class="modal-body">
        <slot></slot>
      </div>
      <div class="modal-footer">
        <button @click="close">取消</button>
        <button @click="confirm">确定</button>
      </div>
    </div>
  </div>
</template>

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

<style scoped>
.modal-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;
}
.modal-container {
  background: white;
  min-width: 300px;
  border-radius: 4px;
  overflow: hidden;
}
.modal-header {
  padding: 16px;
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid #eee;
}
.modal-body {
  padding: 16px;
}
.modal-footer {
  padding: 16px;
  text-align: right;
  border-top: 1px solid #eee;
}
</style>

使用弹窗组件

在父组件中注册并使用弹窗:

<template>
  <div>
    <button @click="showModal = true">打开弹窗</button>
    <Modal 
      v-model:visible="showModal"
      title="提示"
      @confirm="handleConfirm"
    >
      <p>这是弹窗内容</p>
    </Modal>
  </div>
</template>

<script>
import Modal from './Modal.vue'

export default {
  components: { Modal },
  data() {
    return {
      showModal: false
    }
  },
  methods: {
    handleConfirm() {
      console.log('用户点击了确定')
    }
  }
}
</script>

进阶功能实现

动态控制弹窗宽度 在Modal组件中添加width属性:

vue 实现弹窗组件

<script>
export default {
  props: {
    width: {
      type: String,
      default: 'auto'
    }
  }
}
</script>

<style scoped>
.modal-container {
  width: v-bind(width);
}
</style>

添加动画效果 使用Vue的transition组件实现淡入淡出效果:

<template>
  <transition name="fade">
    <div class="modal-mask" v-show="visible" @click.self="close">
      <!-- 其余内容不变 -->
    </div>
  </transition>
</template>

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

全局弹窗服务 创建全局弹窗服务避免重复导入:

vue 实现弹窗组件

// modalService.js
import { createApp } from 'vue'
import Modal from './Modal.vue'

export default {
  install(app) {
    const modalInstance = createApp(Modal).mount(document.createElement('div'))
    document.body.appendChild(modalInstance.$el)

    app.config.globalProperties.$modal = {
      show(options) {
        Object.assign(modalInstance, options)
        modalInstance.visible = true
        return new Promise(resolve => {
          modalInstance.$once('confirm', () => resolve(true))
          modalInstance.$once('update:visible', val => !val && resolve(false))
        })
      }
    }
  }
}

在main.js中注册:

import modalService from './modalService.js'
const app = createApp(App)
app.use(modalService)

使用全局弹窗:

this.$modal.show({
  title: '全局弹窗',
  content: '这是全局弹窗内容'
}).then(confirmed => {
  console.log(confirmed ? '用户确认' : '用户取消')
})

标签: 组件vue
分享给朋友:

相关文章

vue表格实现教学

vue表格实现教学

Vue 表格实现方法 使用原生HTML表格 在Vue模板中直接使用HTML的<table>标签,结合v-for动态渲染数据: <template> <table&g…

vue实现store

vue实现store

Vue 实现 Store 在 Vue 中,可以通过 Vuex 或 Pinia 实现全局状态管理(Store)。以下是两种主流方案的实现方法。 使用 Vuex 实现 Store Vuex 是 Vue…

vue实现曲线

vue实现曲线

Vue 实现曲线的方法 在 Vue 中实现曲线可以通过多种方式,包括使用 SVG、Canvas 或第三方库如 D3.js、ECharts 等。以下是几种常见的方法: 使用 SVG 绘制曲线 SVG…

vue首页实现

vue首页实现

实现Vue首页的基本步骤 创建一个Vue首页通常涉及项目初始化、页面结构设计、路由配置和组件开发。以下是具体实现方法: 初始化Vue项目 使用Vue CLI或Vite快速搭建项目结构: npm i…

vue实现选择置顶

vue实现选择置顶

Vue 实现选择置顶功能 在 Vue 中实现选择置顶功能,可以通过操作数据数组或结合 CSS 样式来实现。以下是几种常见的实现方法: 数组排序法 通过操作数据数组,将被选中的项移动到数组首位: /…

vue滚动加载实现

vue滚动加载实现

vue滚动加载实现 滚动加载是一种常见的优化手段,通过监听滚动事件动态加载数据,减少初始渲染压力。以下是几种实现方式: 使用IntersectionObserver API Intersection…