vue-grid-layout 动态添加删除单元格

vue-grid-layout 动态添加删除单元格,因为vue最基本的功能就是双向绑定,所以只要对 vue-grid-layout 的数据源进行添加删除就可以实现单元格的新增和删除功能。

动态添加删除

 //添加一个单元格
 addItem: function () {       
            this.layout1.push({    
                x: (this.layout1.length * 2) % (this.colNum || 12),    
                y: this.layout1.length + (this.colNum || 12), 
                w: 2,    
                h: 2,    
                i: this.index,    
            });    
            // Increment the counter to ensure key is always unique.    
            this.index++;    
  },  
 //删除单元格  
 removeItem: function (val) {    
            const index = this.layout1.map(item => item.i).indexOf(val);    
            this.layout1.splice(index, 1);    
 },

在线试一试

完整代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>vue-grid-layout 防止碰撞</title>
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
    <script src="https://www.itxst.com/package/vue/vue.min.js"></script>
    <script src="https://www.itxst.com/package/vue-grid-layout/vue-grid-layout.umd.min.js"></script>
</head>
<body style="padding:10px;">
    <div id="app">
        <button @click="addItem">添加单元格</button>
        <grid-layout :prevent-collision="true" :layout.sync="layout1" :col-num="12" :row-height="30">
            <grid-item v-for="item in layout1" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i"
                :key="item.i">
                <span>{{item.i}} <lable @click="removeItem(item.i)">x</lable></span>
            </grid-item>
        </grid-layout>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            components: {
                GridLayout: VueGridLayout.GridLayout,
                GridItem: VueGridLayout.GridItem
            },
            data() {
                return {
                    layout1: [
                        { "x": 0, "y": 0, "w": 2, "h": 2, "i": "0" },
                        { "x": 2, "y": 0, "w": 2, "h": 2, "i": "1" },
                        { "x": 4, "y": 0, "w": 2, "h": 2, "i": "2" },
                        { "x": 0, "y": 1, "w": 6, "h": 2, "i": "3" },
                    ],
                    index: 0,
                };
            },
            mounted() {
                this.index = this.layout1.length;
            },
            methods: {
                //添加一个单元格
                addItem: function () {
                    this.layout1.push({
                        x: (this.layout1.length * 2) % (this.colNum || 12),
                        y: this.layout1.length + (this.colNum || 12),
                        w: 2,
                        h: 2,
                        i: this.index,
                    });
                    // Increment the counter to ensure key is always unique.    
                    this.index++;
                },
                //删除单元格  
                removeItem: function (val) {
                    const index = this.layout1.map(item => item.i).indexOf(val);
                    this.layout1.splice(index, 1);
                },
            }
        });
    </script>
    <style scoped>
        .vue-grid-layout {
            background: #eee;
        }

        .vue-grid-layout span {
            display: flex;
            justify-content: space-between;
        }

        .vue-grid-layout span>lable {
            color: red;
            padding-right: 6px;
            cursor: pointer;

        }

        .vue-grid-item:not(.vue-grid-placeholder) {
            background: #ccc;
            border: 1px solid black;
        }

        .vue-grid-item .resizing {
            opacity: 0.9;
        }

        .vue-grid-item .static {
            background: #cce;
        }

        .vue-grid-item .text {
            font-size: 24px;
            text-align: center;
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
            height: 100%;
            width: 100%;
        }

        .vue-grid-item .no-drag {
            height: 100%;
            width: 100%;
        }

        .vue-grid-item .minMax {
            font-size: 12px;
        }
        .vue-grid-item .add {
            cursor: pointer;
        }
        .vue-draggable-handle {
            position: absolute;
            width: 20px;
            height: 20px;
            top: 0;
            left: 0;
            background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>") no-repeat;
            background-position: bottom right;
            padding: 0 8px 8px 0;
            background-repeat: no-repeat;
            background-origin: content-box;
            box-sizing: border-box;
            cursor: pointer;
        }
    </style>
</body>
</html>