vue+css网格布局随机网格填充进阶版(添加,删除,修改)

接着上篇直接上代码

<template>
  <div>
    <div v-if="showEdit">
      <div @click="checked = '1x1'"><input type="radio" name="1x1" :checked="checked === '1x1'">1x1</div>
      <div @click="checked = '2x1'"><input type="radio" name="2x1" :checked="checked === '2x1'">2x1</div>
      <div @click="checked = '1x2'"><input type="radio" name="1x2" :checked="checked === '1x2'">1x2</div>
      <div @click="checked = '2x2'"><input type="radio" name="2x2" :checked="checked === '2x2'">2x2</div>
    </div>
    <div v-else>
      <button @click="addBox('1x1')">添加1x1</button>
      <button @click="addBox('2x1')">添加2x1</button>
      <button @click="addBox('1x2')">添加1x2</button>
      <button @click="addBox('2x2')">添加2x2</button>
    </div>
    <div>
      <span>盒子颜色:</span>
      <input type="color" :value="boxColor" @change="change" />
    </div>
    <button v-if="showEdit" @click="affirm">确认修改</button>
    <div class="grid-box">
      <div
        v-for="(item, index) in replenish()"
        :key="index"
        :class="['grid-item', {'def-box': item.layout.default}]"
        :style="{
          background: `${item.color || ''}`,
          'grid-area': `${item.layout.star} / ${item.layout.end} / span ${item.layout.row} / span ${item.layout.column}`
        }"
        @dblclick="edit(item)"
      >
        <div @click="delBox(item)" v-if="item.color" class="del">删</div>
      </div>
    </div>
  </div>
</template>

html:

1.在填充盒子中添加了删除按钮和点击删除事件;

2.页面中添加了编辑选中规格和选中颜色的内容;

3.用showEdit字段控制显示隐藏添加和修改;

4.双击填充事件进行修改

<script>
export default {
  data () {
    return {
      checked: '',
      boxColor: '#f90606', // 颜色选择器默认颜色
      matrix: [
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0]
      ], // 定义3行6列的二维数组
      emptyCells: [], // 定义空盒子的数组
      editData: null,
      showEdit: false // 显示编辑
    }
  },
  methods: {
    // 确认修改
    affirm () {
      // 不修改规格只有背景颜色的改变
      if (this.checked === this.editData.size) {
        const obj = this.editData
        this.emptyCells = this.emptyCells.map(item => {
          if (this.editData.id === item.id) {
            return { size: obj.size, layout: obj.layout, color: this.boxColor, id: item.id }
          }
          return item
        })
        this.showEdit = false
      } else { // 修改规格
        const row = this.editData.layout.row
        const column = this.editData.layout.column
        const matrix = JSON.parse(JSON.stringify(this.matrix))
        for (let i = 0; i < row; i++) {
          for (let j = 0; j < column; j++) {
            matrix[this.editData.layout.star - 1 + i][this.editData.layout.end - 1 + j] = 0
          }
        }
        const obj = this.boxMessage(this.checked, matrix)
        if (obj.id) {
          this.emptyCells = this.emptyCells.map(item => {
            if (item.id === this.editData.id) {
              return { size: obj.size, layout: obj.layout, color: obj.color, id: item.id }
            }
            return item
          })
          this.matrix = matrix
          console.log('this.emptyCells:', this.emptyCells)
          console.log('this.matrix:', this.matrix)
          this.replenish()
          this.showEdit = false
        }
      }
    },
    // 双击修改盒子颜色和规格
    edit (item) {
      if (item.id) {
        this.checked = item.size
        this.editData = item
        this.showEdit = true
      }
    },
    // 删除盒子
    delBox (item) {
      this.emptyCells = this.emptyCells.filter(el => el.id !== item.id)
      const row = item.layout.row
      const column = item.layout.column
      for (let i = 0; i < row; i++) {
        for (let j = 0; j < column; j++) {
          this.matrix[item.layout.star - 1 + i][item.layout.end - 1 + j] = 0
        }
      }
      console.log('this.emptyCells-del:', this.emptyCells)
      console.log('this.matrix-del:', this.matrix)
      this.replenish()
    },
    // 颜色选择监听
    change (e) {
      this.boxColor = e.target.value
      console.log(this.boxColor)
    },
    // 添加盒子的函数
    addBox (size) {
      const obj = this.boxMessage(size, this.matrix)
      if (obj.id) {
        // 将盒子的大小和位置添加到空盒子的数组中
        this.emptyCells.push({ size, layout: obj.layout, color: obj.color, id: obj.id })
        console.log('this.emptyCells:', this.emptyCells)
        console.log('this.matrix:', this.matrix)
        this.replenish()
      }
    },
    // 对规格进行判断是否满足条件可以加入规格和对应规格信息
    boxMessage (size, matrix) {
      // matrix = matrix.slice()
      let flag = false
      let layout = {}
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          if (size === '1x1') {
            if (matrix[i][j] === 0) {
              matrix[i][j] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 1, column: 1 }
              break
            }
          } else if (size === '1x2') {
            if (matrix[i][j] === 0 && matrix[i][j + 1] === 0) {
              matrix[i][j] = 1
              matrix[i][j + 1] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 1, column: 2 }
              break
            }
          } else if (size === '2x1') {
            if (matrix[i][j] === 0 && matrix[i + 1] && matrix[i + 1][j] === 0) {
              matrix[i][j] = 1
              matrix[i + 1][j] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 2, column: 1 }
              break
            }
          } else if (size === '2x2') {
            if (matrix[i][j] === 0 &&
              matrix[i][j + 1] === 0 &&
              matrix[i + 1] &&
              matrix[i + 1][j] === 0 &&
              matrix[i + 1][j + 1] === 0
            ) {
              matrix[i][j] = 1
              matrix[i][j + 1] = 1
              matrix[i + 1][j] = 1
              matrix[i + 1][j + 1] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 2, column: 2 }
              break
            }
          }
        }
        if (flag) break
      }
      // 没有合适的空位放了
      if (!flag) {
        console.log('没有合适的位置了')
        return {}
      }
      return { matrix, size, layout, color: this.boxColor, id: new Date().getTime() + '' }
    },
    // 补充剩余的盒子(补充空白的盒子)
    replenish () {
      const matrix = this.matrix
      const box = JSON.parse(JSON.stringify(this.emptyCells))
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          if (matrix[i][j] === 0) {
            const layout = { star: i + 1, end: j + 1, row: 1, column: 1, default: true }
            box.push({ size: '1x1', layout })
          }
        }
      }
      return box
    }
  }
}
</script>

js: 

  1. 对规格判断是否可以填充和可填充的内容信息用boxMessage函数做了封装
  2. edit双击编辑,判断双击的是否是有填充的盒子,拿到规格和当前盒子的所有信息后显示编辑内容
  3. affirm点击编辑内容的确认按钮,先判断是否修改了规格,没有修改规格直接替换颜色,有修改规格先把matrix二维数组拷贝,得到新的matrix,把当前双击的填充盒子在新的matrix的位置变成0,清空所占的位置,调用封装的boxMessage,把规格和新matrix传入,如果还有合适的位置修改规格把新规格替换上,再调用replenish函数重新计算盒子数量
  4. delBox点击删除当前填充和把填充盒子在matrix中的位置变成0,调用replenish重新计算盒子数量
  5. replenish函数对matrix二维数组中为0的都给拷贝的emptyCells存储填充盒子中添加默认的1x1盒子
<style scoped>
.grid-box {
  display: grid;
  grid-template-columns: auto auto auto auto auto auto;
  grid-gap: 20px;
  background-color: #2196F3;
  padding: 10px;
  box-sizing: border-box;
  width: 700px;
  height: 340px;
}

.grid-item {
  background: #ccc;
  position: relative;
}
.del {
  opacity: 0;
  width: 24px;
  height: 24px;
  color: #FFFFFF;
  border-radius: 12px;
  font-size: 12px;
  background: red;
  position: absolute;
  right: -12px;
  top: -12px;
  text-align: center;
  line-height: 24px;
  cursor: pointer;
  transition: 0.3s;
}
.grid-item:hover .del {
  opacity: 1;
}
.def-box {
  background: #FFFFFF;
}
</style>

css:鼠标移入填充盒子显示删除按钮

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有梦想的小猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值