用vue3封装一个符合思维且简单实用的弹出层

yizhihongxing

下面我将详细讲解用vue3封装一个符合思维且简单实用的弹出层的完整攻略。

1. 弹出层的需求分析

在封装弹出层之前,我们需要对需求进行分析,明确所需功能、交互,进而确定实现方式和技术选型。

弹出层的主要需求包括:弹出层中展示数据、支持输入、支持自定义样式、支持关闭、支持拖拽等。

在交互方面,我们需要考虑以下几个问题:

  1. 如何打开/关闭弹出层?
  2. 如何传递数据给弹出层?
  3. 如何获取弹出层中的输入数据?
  4. 如何实现弹出层的拖拽效果?

2. 弹出层的封装实现

在分析完弹出层的需求和交互后,我们开始进行代码实现。

2.1 实现步骤

  1. 创建一个Popup组件,该组件将作为弹出层的整体结构,包括遮罩层、弹出框、标题、内容等。
  2. Popup组件添加到主组件中,通过v-if控制显示或隐藏。
  3. Popup组件中添加slot插槽,用于插入需要展示的内容。
  4. 实现拖拽效果。
  5. Popup组件中添加事件控制,包括关闭事件和确认事件。

2.2 代码实现

<!-- Popup.vue -->

<template>
  <div class="popup-wrapper" v-show="visible">
    <div class="popup-mask" @click="close"></div>
    <div class="popup-container">
      <div class="popup-title">{{title}}</div>
      <div class="popup-content">
        <slot></slot>
      </div>
      <div class="popup-footer">
        <button class="popup-btn popup-cancel" @click="close">取消</button>
        <button class="popup-btn popup-confirm" @click="confirm">确定</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Popup',
  props: {
    title: String,
    visible: Boolean,
    draggable: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      startX: 0,
      startY: 0,
      posX: 0,
      posY: 0
    }
  },
  computed: {
    transform() {
      return `translate3d(${this.posX}px, ${this.posY}px, 0)`
    }
  },
  mounted() {
    if (this.draggable) {
      const header = this.$el.querySelector('.popup-title')
      header.style.cursor = 'move'
      header.addEventListener('mousedown', this.startDrag)
    }
  },
  beforeUnmount() {
    if (this.draggable) {
      const header = this.$el.querySelector('.popup-title')
      header.removeEventListener('mousedown', this.startDrag)
    }
  },
  methods: {
    startDrag(event) {
      this.startX = event.clientX
      this.startY = event.clientY
      this.posX = this.$el.offsetLeft
      this.posY = this.$el.offsetTop
      document.addEventListener('mousemove', this.drag)
      document.addEventListener('mouseup', this.stopDrag)
    },
    drag(event) {
      const deltaX = event.clientX - this.startX
      const deltaY = event.clientY - this.startY
      this.posX += deltaX
      this.posY += deltaY
      this.startX = event.clientX
      this.startY = event.clientY
    },
    stopDrag() {
      document.removeEventListener('mousemove', this.drag)
      document.removeEventListener('mouseup', this.stopDrag)
    },
    close() {
      this.$emit('update:visible', false)
    },
    confirm() {
      this.$emit('confirm')
      this.close()
    }
  }
}
</script>

<style scoped>
.popup-wrapper {
  position: fixed;
  z-index: 9999;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.popup-mask {
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, .5);
}

.popup-container {
  position: relative;
  width: 400px;
  max-height: 600px;
  border-radius: 6px;
  background-color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .1);
  overflow: auto;
  transition: transform .3s ease-out;
  transform: translateY(-50%);
}

.popup-title {
  padding: 12px 16px;
  font-size: 16px;
  font-weight: bold;
  text-align: center;
}

.popup-content {
  padding: 16px;
}

.popup-footer {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 16px 0;
}

.popup-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  outline: none;
}

.popup-confirm {
  color: #fff;
  background-color: #42b983;
  margin-left: 16px;
}

.popup-cancel:hover,
.popup-confirm:hover {
  opacity: .8;
}

.popup-title {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.popup-title:active {
  cursor: move;
}
</style>

在主组件中使用Popup组件:

<template>
  <div>
    <!-- 弹出层触发按钮 -->
    <button @click="visible = true">打开弹出层</button>
    <!-- 弹出层 -->
    <Popup
      :visible.sync="visible"
      title="弹出层标题"
      @confirm="confirmHandler"
    >
      <p>这里是弹出层内容</p>
    </Popup>
  </div>
</template>

<script>
import Popup from './components/Popup.vue'

export default {
  name: 'App',
  components: { Popup },
  data() {
    return {
      visible: false
    }
  },
  methods: {
    confirmHandler() {
      console.log('点击了确认')
    }
  }
}
</script>

3. 示例说明

下面给出2个示例,以更好地说明Popup组件的用法。

3.1 示例一:弹出层展示表单

利用Popup组件展示一个表单,包括姓名、年龄、性别等字段:

<template>
  <div>
    <!-- 弹出层触发按钮 -->
    <button @click="visible = true">打开弹出层</button>
    <!-- 弹出层 -->
    <Popup
      :visible.sync="visible"
      title="填写信息"
      @confirm="confirmHandler"
    >
      <form>
        <div class="form-group">
          <label for="name">姓名</label>
          <input id="name" type="text" v-model="formData.name" />
        </div>
        <div class="form-group">
          <label for="age">年龄</label>
          <input id="age" type="number" v-model.number="formData.age" />
        </div>
        <div class="form-group">
          <label for="gender">性别</label>
          <select id="gender" v-model="formData.gender">
            <option value="">请选择</option>
            <option value="male">男</option>
            <option value="female">女</option>
          </select>
        </div>
        <button type="submit">提交</button>
      </form>
    </Popup>
  </div>
</template>

<script>
import Popup from './components/Popup.vue'

export default {
  name: 'App',
  components: { Popup },
  data() {
    return {
      visible: false,
      formData: {
        name: '',
        age: 0,
        gender: ''
      }
    }
  },
  methods: {
    confirmHandler() {
      console.log('表单提交', this.formData)
    }
  }
}
</script>

3.2 示例二:弹出层展示自定义内容

利用Popup组件展示一张图片,支持拖拽:

<template>
  <div>
    <!-- 弹出层触发按钮 -->
    <button @click="visible = true">打开弹出层</button>
    <!-- 弹出层 -->
    <Popup
      :visible.sync="visible"
      title="图片预览"
      @confirm="confirmHandler"
    >
      <img
        src="https://picsum.photos/600/400"
        alt="图片"
        @mousedown.stop.prevent="startDrag"
        :style="{ transform }"
      />
    </Popup>
  </div>
</template>

<script>
import Popup from './components/Popup.vue'

export default {
  name: 'App',
  components: { Popup },
  data() {
    return {
      visible: false,
      startX: 0,
      startY: 0,
      posX: 0,
      posY: 0
    }
  },
  computed: {
    transform() {
      return `translate3d(${this.posX}px, ${this.posY}px, 0)`
    }
  },
  methods: {
    startDrag(event) {
      this.startX = event.clientX
      this.startY = event.clientY
      this.posX = event.target.offsetLeft
      this.posY = event.target.offsetTop
      document.addEventListener('mousemove', this.drag)
      document.addEventListener('mouseup', this.stopDrag)
    },
    drag(event) {
      const deltaX = event.clientX - this.startX
      const deltaY = event.clientY - this.startY
      this.posX += deltaX
      this.posY += deltaY
      this.startX = event.clientX
      this.startY = event.clientY
    },
    stopDrag() {
      document.removeEventListener('mousemove', this.drag)
      document.removeEventListener('mouseup', this.stopDrag)
    },
    confirmHandler() {
      console.log('关闭弹出层')
    }
  }
}
</script>

以上是用vue3封装一个符合思维且简单实用的弹出层的完整攻略,希望对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用vue3封装一个符合思维且简单实用的弹出层 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • officejsexcel加载项的首选ide

    以下是关于“OfficeJS Excel加载项的首选IDE”的完整攻略,包含两个示例。 OfficeJS Excel加载项的首选IDE OfficeJS Excel加载项是一种用于在Excel中添加自定义功能的技术。在开发OfficeJS Excel加载项时,选择一个适合的IDE非常重要。以下是关于如何选择OfficeJS Excel加载项的首选IDE的详细…

    other 2023年5月9日
    00
  • IIC双向电平转换电路设计

    IIC双向电平转换电路设计 IIC是一种串行通信总线协议,常用于连接各种微控制器、传感器、存储器等设备。IIC总线包括数据线SDA和时钟线SCL,其中数据线需要双向通信。然而,不同设备之间的IIC电平标准不同,有些是3.3V,有些是5V,因此需要双向电平转换电路来实现不同电平设备之间的通信。 电路设计 下面介绍一种简单的IIC双向电平转换电路设计,如下图所示…

    其他 2023年3月28日
    00
  • UEFI开发基础汇编代码的使用

    下面我将详细讲解UEFI开发基础汇编代码的使用的完整攻略。首先需要知道,UEFI开发时一般使用C语言作为主要开发语言,但是在某些特殊情况下,需要使用汇编代码来完成一些底层的操作。下面就是使用汇编代码的完整攻略: 步骤一:搭建开发环境 在使用汇编代码进行UEFI开发前,需要先搭建好开发环境。搭建UEFI开发环境需要有以下几个步骤:1. 安装Visual Stu…

    other 2023年6月26日
    00
  • Lua在各个操作系统中的开发环境配置教程

    Lua在各个操作系统中的开发环境配置教程 Windows操作系统 在官网下载最新版的Lua安装包。 打开安装包,按照安装向导的提示进行安装。选择安装路径时,最好将路径添加到系统环境变量中,这样才能在任意文件夹中使用Lua命令。 安装完成后,在命令提示符中输入lua -v,如果提示Lua的版本信息,则证明安装成功。 推荐使用ZeroBrane Studio作为…

    other 2023年6月26日
    00
  • Android Service(不和用户交互应用组件)案例分析

    Android Service Android中,Service是一种后台运行的组件,通常用于执行长时间运行的任务或在后台处理某些操作。Service运行于后台,不与用户进行交互,因此在使用时需要注意内存泄漏及后台任务执行的时间不要过长等问题。 Service的创建与启动 Service的创建方式有两种:一种是继承Service类并实现其中的方法;另一种是继…

    other 2023年6月27日
    00
  • Docker垃圾回收机制

    下面是“Docker垃圾回收机制的完整攻略”的详细讲解,包括垃圾回收机制的概述、过程和两个示例等方面。 垃圾回收机制的概述 Docker垃圾回收机制是一种自动化的机制,用于清理不再使用的Docker镜像和容器。当Docker镜像或容器不再使用时,它们会占用磁盘空间,可能会导致磁盘空间不足。垃圾回收机制可以定期清理这些不再使用的镜像和容器,从而释放磁盘空间。 …

    other 2023年5月6日
    00
  • 如何linux环境下配置环境变量过程图解

    下面是详细的Linux环境下配置环境变量的攻略,包含了过程图解和两个示例说明。 配置环境变量的过程 步骤1:进入bash shell 打开Linux终端,并进入bash shell。如果你不确定自己是否已经进入bash shell,可以输入以下命令: echo $0 如果输出结果为”bash”,则表示已经成功进入bash shell。 步骤2:查看当前环境变…

    other 2023年6月27日
    00
  • web前端轮询获取数据的定义及优劣

    Web前端轮询获取数据的定义及优劣 Web前端轮询获取数据是一种常见的客户端与服务器通信方式,用于实时获取服务器端的数据。本文将介绍Web前端轮询获取数据的定义优劣,包括轮询的概念、轮询的优劣、轮询的实现方式等。 轮询的概念 轮询是一种客户端与服务器通信方式,客户端定期向服务器发送请求,以获取最新的数据。在Web前端中,轮询通常使用Ajax技术实现,即通过X…

    other 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部