vue-grid-layout
vue-grid-layout copied to clipboard
Adding "ref" attribute to grid item
Good day,
With Vue to quickly reference a dom element in a vue template, one can add ref attribute to the html.
Can we add this to the grid-item as a property then it can be directly available, ie, we can programattically refere to a specific grid item in our script code, and add, components, etc to a specific item dynamically.
hi, I faced the same problem. After I try several days, I use it in this way and it works.
I use Vue 3+Typescript+vite. I tried to grab a new grid-item form outside and dymanic add it into my gridLayout.

basically use this code: https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example10DragFromOutside.vue
I faced the problem that $children is removed in Vue3,so I changed the usage of Vue 2 into Vue 3.
// sample code
this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = "none";
// change into
var gridlayout = ref()
gridlayout.value.$refs.item.children[index].style.display = "none";
but by this way, I can't call the method "calXY()" in gridItem. the problematic code in the sample:
// get the grid-item
let el = this.$refs.gridlayout.$children[index];
// call grid-item function to calculate the new position
let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);
At first I used gridLayout ref,trying to get its children(gridItem) like the sample.
it's like this:
gridlayout.value.$refs.item.children[index].__vueParentComponent.proxy.calcXY()
It works only under development mode.
and I tried to use ref. Because grid-item is rendered by v-for, so its ref need to write a function to get every item. I only need the last grid-item ref.
<grid-item
v-for="item in layout"
:key="item.i"
:ref="setItemRef"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i='item.i'
>
your item here
</grid-item>
// get the last grid-item ref
var temp_item = ref()
function setItemRef(el:any){
// if you need the all ref, you can't use the ref<Array<type>> and push el into array directly
// as long as you haven't released the left mouse button, it will keep changing the ref value
// so if you push it into the array directly, array will get longer and longer
temp_item.value = el
}
so now I have the last grid-item ref. the first time you drag it into the gridlayout, temp_item.value will get null. so just need an if:
if(temp_item.value){
let el = temp_item.value
el.dragging = {"top": mouseXY.y - parentRect.top, "left": mouseXY.x - parentRect.left}
let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left)
}
because only the new item will call drag() and dragend(), so it only affects the latest one (meaning the newly added gridItem).
this works well in production mode. I just learned Vue 3 several months. if anything wrong, plz tell me. hope this comes in handy