当前位置:首页 > VUE

vue实现抽屉组件

2026-02-19 11:19:47VUE

实现基础抽屉组件结构

使用 Vue 的单文件组件方式创建抽屉组件,核心结构包含遮罩层、抽屉主体和内容插槽:

<template>
  <div class="drawer-container">
    <div 
      class="drawer-mask" 
      v-show="visible"
      @click="handleMaskClick">
    </div>

    <div 
      class="drawer-wrapper"
      :class="[placement, { 'visible': visible }]">
      <div class="drawer-content">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

定义组件属性与事件

通过 props 控制抽屉行为,包括显示状态、位置和点击遮罩是否关闭:

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    placement: {
      type: String,
      default: 'right',
      validator: (value) => ['top', 'right', 'bottom', 'left'].includes(value)
    },
    maskClosable: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    handleMaskClick() {
      if (this.maskClosable) {
        this.$emit('update:visible', false);
      }
    }
  }
}
</script>

添加基础样式

实现抽屉动画效果和不同位置的定位:

<style scoped>
.drawer-container {
  position: relative;
}

.drawer-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
}

.drawer-wrapper {
  position: fixed;
  z-index: 1001;
  transition: all 0.3s;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.drawer-wrapper.right {
  top: 0;
  right: 0;
  height: 100%;
  transform: translateX(100%);
}

.drawer-wrapper.left {
  top: 0;
  left: 0;
  height: 100%;
  transform: translateX(-100%);
}

.drawer-wrapper.top {
  top: 0;
  left: 0;
  width: 100%;
  transform: translateY(-100%);
}

.drawer-wrapper.bottom {
  bottom: 0;
  left: 0;
  width: 100%;
  transform: translateY(100%);
}

.drawer-wrapper.visible.right,
.drawer-wrapper.visible.left {
  transform: translateX(0);
}

.drawer-wrapper.visible.top,
.drawer-wrapper.visible.bottom {
  transform: translateY(0);
}

.drawer-content {
  width: 100%;
  height: 100%;
  overflow: auto;
}
</style>

添加标题和关闭按钮

增强抽屉组件的功能性,添加标题栏和关闭控制:

<template>
  <!-- 原有结构基础上添加 -->
  <div class="drawer-header" v-if="title || showClose">
    <span class="drawer-title">{{ title }}</span>
    <button 
      v-if="showClose"
      class="drawer-close"
      @click="$emit('update:visible', false)">
      ×
    </button>
  </div>
</template>

<script>
export default {
  props: {
    title: String,
    showClose: {
      type: Boolean,
      default: true
    }
    // 其他原有props...
  }
}
</script>

<style scoped>
.drawer-header {
  padding: 16px 24px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.drawer-title {
  font-size: 16px;
  font-weight: 500;
}

.drawer-close {
  font-size: 18px;
  cursor: pointer;
  background: transparent;
  border: none;
}
</style>

控制抽屉宽度/高度

通过 props 允许自定义抽屉尺寸:

props: {
  width: {
    type: [String, Number],
    default: '30%'
  },
  height: {
    type: [String, Number],
    default: '30%'
  }
}
<div 
  class="drawer-wrapper"
  :class="[placement, { 'visible': visible }]"
  :style="placement === 'left' || placement === 'right' 
    ? { width: typeof width === 'number' ? `${width}px` : width }
    : { height: typeof height === 'number' ? `${height}px` : height }">
  <!-- 内容不变 -->
</div>

实现嵌套抽屉支持

修改 z-index 策略避免嵌套抽屉冲突:

data() {
  return {
    zIndex: this.getNextZIndex()
  };
},
methods: {
  getNextZIndex() {
    let zIndex = 1000;
    const drawers = document.querySelectorAll('.drawer-mask');
    if (drawers.length > 0) {
      zIndex = Number(window.getComputedStyle(drawers[drawers.length - 1]).zIndex) + 1;
    }
    return zIndex;
  }
}
<div 
  class="drawer-mask" 
  v-show="visible"
  :style="{ zIndex }"
  @click="handleMaskClick">
</div>

<div 
  class="drawer-wrapper"
  :style="{
    zIndex: zIndex + 1,
    ...placementStyle
  }">
  <!-- 内容不变 -->
</div>

vue实现抽屉组件

标签: 抽屉组件
分享给朋友:

相关文章

vue实现组件循环图片

vue实现组件循环图片

Vue 实现组件循环图片的方法 在 Vue 中实现组件循环图片通常可以通过 v-for 指令结合动态数据绑定完成。以下是几种常见的实现方式: 使用静态图片路径数组 假设有一组本地图片路径,可以通过…

vue实现倒计时组件

vue实现倒计时组件

Vue 倒计时组件实现 核心思路 通过 setInterval 或 setTimeout 实现时间递减,结合 Vue 的响应式数据更新 UI。需注意组件销毁时清除定时器。 基础实现方案 模板部分…

vue实现折叠组件

vue实现折叠组件

实现折叠组件的基本思路 在Vue中实现折叠组件通常需要利用动态绑定和条件渲染。核心是通过控制一个布尔值状态来决定内容是否显示,并添加过渡动画提升用户体验。 基础实现方法 使用v-show或v-if…

react组件如何通讯

react组件如何通讯

React 组件通讯方式 React 组件间的通讯方式主要包括以下几种方法,适用于不同场景下的数据传递和状态管理需求。 父子组件通讯(Props 传递) 父组件通过 props 向子组件传递数据或回…

如何设计react组件

如何设计react组件

设计 React 组件的核心原则 React 组件的设计需要遵循高内聚、低耦合的原则,确保组件功能独立且易于维护。组件的设计可以分为展示组件和容器组件两类,展示组件负责 UI 渲染,容器组件负责逻辑处…

uniapp 滑动组件

uniapp 滑动组件

uniapp 滑动组件实现方法 使用swiper组件 uniapp内置的swiper组件可以实现滑动效果,适用于轮播图或页面切换场景。 示例代码: <swiper :indicator-…