Skip to content

Commit cc8f228

Browse files
Add Vue.js example
Adds a basic example of how to integrate GridStack with a Vue.js app. This demo requires a modestly modern browser, but Vue has a legacy build mode when using single file components with Vue CLI.
1 parent cf39316 commit cc8f228

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

demo/vuejs.html

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Gridstack.js Vue integration example</title>
7+
<link
8+
rel="stylesheet"
9+
href="https://cdn.jsdelivr.net/npm/gridstack@2.0.0/dist/gridstack.min.css"
10+
/>
11+
12+
<script src="https://cdn.jsdelivr.net/npm/gridstack@2.0.0/dist/gridstack.all.js"></script>
13+
<style>
14+
.grid-stack {
15+
background: #fafad2;
16+
}
17+
.grid-stack-item-content {
18+
color: #2c3e50;
19+
text-align: center;
20+
background-color: #18bc9c;
21+
}
22+
</style>
23+
</head>
24+
<body>
25+
<main id="app">
26+
<h1>How to integrate GridStack.js with Vue.js</h1>
27+
<p>
28+
As with any virtualDOM-based framework, you need to check if Vue has
29+
rendered the DOM (or any updates to it) <strong>before</strong> you
30+
initialize GridStack or call its methods. As a basic example, check this
31+
component's <code>mounted</code> hook.
32+
</p>
33+
<p>
34+
If your app requires more complex render logic than the inline template
35+
in `addWidget`, consider
36+
<a
37+
href="https://github.com/gridstack/gridstack.js/tree/develop/doc#makewidgetel"
38+
>makeWidget</a
39+
>
40+
to let Vue deal with DOM rendering.
41+
</p>
42+
<p>{{ info }}</p>
43+
<button type="button" @click="addNewWidget()">Add Widget</button>
44+
<section class="grid-stack"></section>
45+
</main>
46+
<script type="module">
47+
import Vue from "https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.esm.browser.js";
48+
49+
let app = new Vue({
50+
el: "#app",
51+
data: {
52+
// Reference to the GridStack instance to access it later
53+
grid: undefined,
54+
count: 0,
55+
info: "",
56+
timerId: undefined,
57+
},
58+
items: [
59+
{ x: 2, y: 1, width: 1, height: 2 },
60+
{ x: 2, y: 4, width: 3, height: 1 },
61+
{ x: 4, y: 2, width: 1, height: 1 },
62+
{ x: 3, y: 1, width: 1, height: 2 },
63+
{ x: 0, y: 6, width: 2, height: 2 },
64+
],
65+
watch: {
66+
/**
67+
* Clear the info text after a two second timeout. Clears previous timeout first.
68+
*/
69+
info: function (newVal, oldVal) {
70+
if (newVal.length === 0) return;
71+
72+
window.clearTimeout(this.timerId);
73+
this.timerId = window.setTimeout(() => {
74+
this.info = "";
75+
}, 2000);
76+
},
77+
},
78+
mounted: function () {
79+
// Provides access to the GridStack instance across the Vue component.
80+
this.grid = GridStack.init({ float: true });
81+
82+
// Use an arrow function so that `this` is bound to the Vue instance. Alternatively, use a custom Vue directive on the `.grid-stack` container element: https://vuejs.org/v2/guide/custom-directive.html
83+
this.grid.on("dragstop", (event, element) => {
84+
const node = event.target.gridstackNode;
85+
// `this` will only access your Vue instance if you used an arrow function, otherwise `this` binds to window scope. see https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/
86+
this.info = `You just dragged node #${node.id} to x${node.x} y${node.y} – good job!`;
87+
});
88+
},
89+
methods: {
90+
addNewWidget: function () {
91+
const node = this.$options.items[this.count] || {
92+
x: Math.round(12 * Math.random()),
93+
y: Math.round(5 * Math.random()),
94+
width: Math.round(1 + 3 * Math.random()),
95+
height: Math.round(1 + 3 * Math.random()),
96+
};
97+
this.count++;
98+
this.grid.addWidget(
99+
`<div><div class="grid-stack-item-content">${this.count}</div></div>`,
100+
{ id: this.count, ...node }
101+
);
102+
},
103+
},
104+
});
105+
</script>
106+
</body>
107+
</html>

0 commit comments

Comments
 (0)