接着上篇直接上代码
<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:
- 对规格判断是否可以填充和可填充的内容信息用boxMessage函数做了封装
- edit双击编辑,判断双击的是否是有填充的盒子,拿到规格和当前盒子的所有信息后显示编辑内容
- affirm点击编辑内容的确认按钮,先判断是否修改了规格,没有修改规格直接替换颜色,有修改规格先把matrix二维数组拷贝,得到新的matrix,把当前双击的填充盒子在新的matrix的位置变成0,清空所占的位置,调用封装的boxMessage,把规格和新matrix传入,如果还有合适的位置修改规格把新规格替换上,再调用replenish函数重新计算盒子数量
- delBox点击删除当前填充和把填充盒子在matrix中的位置变成0,调用replenish重新计算盒子数量
- 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:鼠标移入填充盒子显示删除按钮