当前位置:首页 > 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 控制抽屉行为,包括显示状态、位置和点击遮罩是否关闭:

vue实现抽屉组件

<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>

添加标题和关闭按钮

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

vue实现抽屉组件

<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>

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

相关文章

react如何开发组件

react如何开发组件

React 组件开发基础 React 组件分为函数组件和类组件两种形式。函数组件是现代 React 开发的主流方式,结合 Hooks 可以实现完整功能。 函数组件示例: function Gree…

uniapp组件写法

uniapp组件写法

Uniapp 组件的基本写法 Uniapp 的组件写法与 Vue 类似,支持单文件组件(.vue 文件)。一个基本的组件通常包含三个部分:<template>、<script>…

elementui抽屉

elementui抽屉

elementui抽屉的基本用法 Element UI的抽屉组件(Drawer)是一种从页面边缘滑出的面板,常用于显示额外内容或操作。需要在项目中引入Element UI库后使用。 安装Elemen…

react如何引入组件

react如何引入组件

引入组件的常见方法 直接导入组件文件 通过import语句从指定路径引入组件文件,适用于项目内自定义组件。假设组件文件位于./components/Button.js: import Button…

vue实现search组件

vue实现search组件

Vue 实现搜索组件 基础实现 创建一个基础的搜索组件需要包含输入框和搜索逻辑。以下是一个简单的实现示例: <template> <div class="search-cont…

vue 实现弹窗组件

vue 实现弹窗组件

Vue 弹窗组件实现 基础弹窗组件结构 创建一个名为Modal.vue的文件,定义弹窗的基础结构和样式: <template> <div class="modal-mask"…