-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
vue3js_v-for.html
163 lines (145 loc) · 5.29 KB
/
vue3js_v-for.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue3 v-for Gridstack</title>
<link rel="stylesheet" href="demo.css" />
<script src="../dist/gridstack-all.js"></script>
</head>
<body>
<main id="app">
<h1>How to integrate GridStack.js with Vue.js</h1>
<p>
As with any virtual DOM based framework, you need to check if Vue has
rendered the DOM (or any updates to it) <strong>before</strong> you
initialize GridStack or call its methods. As a basic example, check this
component's <code>mounted</code> hook.
</p>
<p>
If your app requires more complex render logic than the inline template
in `addWidget`, consider
<a href="https://github.com/gridstack/gridstack.js/tree/master/doc#makewidgetel">makeWidget</a>
to let Vue deal with DOM rendering.
</p>
<button type="button" @click="addNewWidget2()">Add Widget pos [0,0]</button>
<button type="button" @click="removeLastWidget()">Remove Last Widget</button>
<br>
<br>
<button type="button" @click="changeFloat()">Float: {{gridFloat}}</button>
<div>{{ info }}</div>
<br>
<div><b :style="{color: color}">{{ gridInfo }}</b></div>
<br>
<div class="grid-stack">
<div v-for="(w, indexs) in items" class="grid-stack-item" :gs-x="w.x" :gs-y="w.y" :gs-w="w.w" :gs-h="w.h"
:gs-id="w.id" :id="w.id" :key="w.id">
<div class="grid-stack-item-content">
<button @click="remove(w)">remove</button>
{{w}}
</div>
</div>
</div>
</main>
<script type="module">
import { createApp, ref, onMounted, nextTick } from "https://cdn.jsdelivr.net/npm/vue@3.0.11/dist/vue.esm-browser.js";
createApp({
setup() {
let count = ref(0);
let info = ref("");
let gridFloat = ref(false);
let color = ref("black");
let gridInfo = ref("");
let grid = null; // DO NOT use ref(null) as proxies GS will break all logic when comparing structures... see https://github.com/gridstack/gridstack.js/issues/2115
let items = ref([]);
onMounted(() => {
grid = GridStack.init({ // DO NOT user grid.value = GridStack.init(), see above
float: false,
cellHeight: "70px",
minRow: 1,
});
grid.on("dragstop", function (event, element) {
const node = element.gridstackNode;
info.value = `you just dragged node #${node.id} to ${node.x},${node.y} – good job!`;
});
grid.on('change', onChange);
// gridFloat.value = grid.float();
});
function changeFloat() {
gridFloat.value = !gridFloat.value;
grid.float(gridFloat.value);
}
function onChange(event, changeItems) {
updateInfo();
// update item position
changeItems.forEach(item => {
var widget = items.value.find(w => w.id == item.id);
if (!widget) {
alert("Widget not found: " + item.id);
return;
}
widget.x = item.x;
widget.y = item.y;
widget.w = item.w;
widget.h = item.h;
});
}
function addNewWidget2() {
const node = items[count.value] || { x: 0, y: 0, w: 2, h: 2 };
node.id = 'w_'+ (count.value++);
// grid.addWidget(node);
items.value.push(node);
nextTick(()=>{
grid.makeWidget(node.id);
updateInfo();
});
}
function removeLastWidget() {
if (count.value == 0) return;
var id = `w_${count.value-1}`;
var index = items.value.findIndex(w => w.id == id);
if (index < 0) return;
var removed = items.value[index];
remove(removed);
}
function remove(widget) {
var index = items.value.findIndex(w => w.id == widget.id);
items.value.splice(index, 1);
const selector = `#${widget.id}`;
grid.removeWidget(selector, false);
updateInfo();
}
function updateInfo() {
color.value = grid.engine.nodes.length == items.value.length ? "black" : "red";
gridInfo.value = `Grid engine: ${grid.engine.nodes.length}, widgets: ${items.value.length}`;
}
return {
info,
items,
addNewWidget2,
removeLastWidget,
onChange,
grid,
gridInfo,
remove,
gridFloat,
changeFloat,
color
};
},
watch: {
/**
* Clear the info text after a two second timeout. Clears previous timeout first.
*/
info: function (newVal) {
if (newVal.length === 0) return;
window.clearTimeout(this.timerId);
this.timerId = window.setTimeout(() => {
this.info = "";
}, 2000);
},
},
}).mount("#app");
</script>
</body>
</html>