-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue3 demo issue with 2 grids #2214
Comments
playing with the demo I could also find myself in a situation where 2 widgets overlap. A widget get's behind another and when I move the one at the top, the one beneath moves, 1 sec after, on the same spot I dropped my first widget |
I do not recommend v-for usage - see my Angular Copomnent explaination why for loops are only for very very simple cases IMO... maybe someone can create a Vue version of my angular components and examples. |
I would love to have a high quality wrapper for Vue (and React) as I've now created one for Angular (what I use at work) - clearly keeping gridstack neutral (plain TS) as frameworks come and go.... I don't know Vue, but for more advanced things (multiple grids drag&drop, nested grids, dragging from toolbar to add/remove items) is it best to let gridstack do all the DOM manipulation as trying to sync between framework and GS becomes complex quickly. This is what I've done in the Angular wrapper - gridstack calls back using The current React & Vue use the for loop which quickly falls appart IMO (I have the same for Angular but discourage for only the simplest things (display a grid from some data, with little modification by user) |
Sharing my vue (vue3) solution in case it's helpful, and I'm also interested to see how other folks have rolled their own. This gives full control to Gridstack to handle creating and removing items, I hook into the <script setup lang="ts">
import { h, onMounted, render, watchEffect } from 'vue'
let grid: GridStack | null = null;
onMounted(() => {
grid = GridStack.init({
margin: 12,
cellHeight: 100,
float: true,
disableOneColumnMode: true,
acceptWidgets: true,
minRow: 1,
})
grid.on('added', function(event: Event, items: GridStackNode[]) {
for (const item of items) {
const itemEl = item.el as HTMLElement
const itemElContent = itemEl.querySelector('.grid-stack-item-content') as HTMLElement
const widgetId = item.id
if (typeof widgetId === 'undefined') {
continue
}
// dynamically render a vue component, and append it to the grid stack item content
// https://vuejs.org/guide/extras/render-function.html
const widgetNode = h(SpaceWidget, { widgetId })
render(widgetNode, itemElContent)
}
});
grid.on('removed', function(event, items) {
for (const item of items) {
const itemEl = item.el
const itemElContent = itemEl.querySelector('.grid-stack-item-content')
// Unmount the vue node from the item element
// Calling render with null will allow vue to clean up the DOM, and trigger lifecycle hooks
render(null, itemElContent)
}
});
watchEffect(() => {
grid?.load(<gridstack settings>)
})
});
</script>
<template>
<div class="grid-stack grow shrink-0 w-full h-full"></div>
</template> |
| This gives full control to Gridstack to handle creating and removing items that's great and it would be great if you could add an running vue example like the other ones already posted... |
I'll open a PR today with new demos using
Yes! Good catch, thank you. I've updated my own code to handle remove, and will include it in the demos. |
right, so instead of using added/removed events, we might want to use GridStack.addRemoveCB but in your case (unlike the Angualr wrapper I include) you want the 2 divs and only then do you add your component inside the content div. I was thinking we could extract the div creation out and have GS use it, or your code use it before adding Vue component inside content. |
@thalida I am trying to adapt your example for our dashboard. but the problem I am facing is that my manually rendered components do not have access to the rest of my app. in particular global functions we add to Edit: I found a way to hack it by writing createdWidgetVNode.appContext = this.appContext || null and first storing appContext in my parent component in setup() from getCurrentInstance()?.appContext. However the above code still doesn't work in the case where my component gets re-rendered. My component is in a keep-alive tab component and when I change to another tab and back, the tab becomes visible and it wants to re-render. All my gridstack widgets are rendered but are disconnected from the gridstack so they have no height and working layout anymore. |
This method specifies that the drag handle selector 'handle:'. handleClass' is invalid. How can I solve this problem |
Hi @rocifier, did you find any solution to the |
@carum98 this solution worked for me.
|
nice bro! |
Thanks |
Page url: https://gridstackjs.com/demo/vue3js_v-for.html
When I add two grid, then remove one of them, the rest could not draggable.
The text was updated successfully, but these errors were encountered: