You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vue.js实现卡片右侧/底部动态定位与可配置尺寸卡片添加功能

Vue 动态可扩展网格卡片实现方案

功能特性

我们要实现的卡片扩展功能支持以下能力:

  • 页面初始化时自动渲染首张基础卡片
  • 每张卡片自带两个操作按钮:点击右侧按钮将在当前卡片右侧新增卡片,点击底部按钮将在当前卡片下方新增卡片
  • 所有尺寸参数支持动态配置:卡片宽度、卡片高度、卡片横向间距、卡片纵向间距

实现思路

用二维数组存储卡片网格结构,数组第一层对应行,第二层对应每行内的卡片,每个卡片存储唯一标识用于渲染区分。操作按钮触发时对应修改二维数组结构即可实现新增效果:

  • 右侧新增:找到当前卡片所在行的下标位置,在该位置后插入新卡片元素
  • 底部新增:在二维数组末尾新增一行,行内放入新卡片元素

核心实现代码

模板代码

<template>
  <div class="card-container" :style="containerStyle">
    <div v-for="(row, rowIndex) in cardGrid" :key="`row-${rowIndex}`" class="card-row" :style="rowStyle">
      <div v-for="(card, colIndex) in row" :key="card.id" class="card-item" :style="cardStyle">
        <!-- 卡片自定义内容区域 -->
        <div class="card-content">{{ card.content }}</div>
        <!-- 右侧新增按钮 -->
        <button class="add-btn right-btn" @click="addRightCard(rowIndex, colIndex)">+</button>
        <!-- 底部新增按钮,可去掉v-if实现每张卡片都显示底部新增按钮 -->
        <button v-if="colIndex === row.length - 1" class="add-btn bottom-btn" @click="addBottomCard()">+</button>
      </div>
    </div>
  </div>
</template>

逻辑代码

<script>
export default {
  name: 'DynamicCardGrid',
  props: {
    // 卡片宽度,单位px
    cardWidth: {
      type: Number,
      default: 200
    },
    // 卡片高度,单位px
    cardHeight: {
      type: Number,
      default: 150
    },
    // 卡片之间的横向间距,单位px
    horizontalGap: {
      type: Number,
      default: 16
    },
    // 卡片之间的纵向间距,单位px
    verticalGap: {
      type: Number,
      default: 16
    }
  },
  data() {
    return {
      // 卡片网格二维数据,初始化自带第一张卡片
      cardGrid: [
        [{ id: Date.now(), content: '卡片1' }]
      ],
      idCounter: 1
    }
  },
  computed: {
    containerStyle() {
      return {
        padding: `${this.verticalGap}px ${this.horizontalGap}px`
      }
    },
    rowStyle() {
      return {
        marginBottom: `${this.verticalGap}px`,
        gap: `${this.horizontalGap}px`
      }
    },
    cardStyle() {
      return {
        width: `${this.cardWidth}px`,
        height: `${this.cardHeight}px`
      }
    }
  },
  methods: {
    // 右侧新增卡片
    addRightCard(rowIndex, colIndex) {
      this.idCounter++
      const newCard = {
        id: Date.now() + this.idCounter,
        content: `卡片${this.idCounter}`
      }
      this.cardGrid[rowIndex].splice(colIndex + 1, 0, newCard)
    },
    // 底部新增卡片
    addBottomCard() {
      this.idCounter++
      const newCard = {
        id: Date.now() + this.idCounter,
        content: `卡片${this.idCounter}`
      }
      this.cardGrid.push([newCard])
    }
  }
}
</script>

样式代码

<style scoped>
.card-container {
  box-sizing: border-box;
  width: 100%;
}
.card-row {
  display: flex;
  align-items: flex-start;
}
.card-item {
  position: relative;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.card-content {
  padding: 12px;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
.add-btn {
  position: absolute;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: #165dff;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
}
.right-btn {
  right: -12px;
  top: 50%;
  transform: translateY(-50%);
}
.bottom-btn {
  bottom: -12px;
  left: 50%;
  transform: translateX(-50%);
}
.add-btn:hover {
  background: #0f4bd1;
}
</style>

组件使用方式

在父组件引入后可直接通过props自定义配置参数:

<DynamicCardGrid 
  :cardWidth="220"
  :cardHeight="160"
  :horizontalGap="20"
  :verticalGap="20"
/>

内容的提问来源于stack exchange,提问作者Chrollo Desu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:12:00