[Vuejs]-Change ownership of Vue Component

0👍

Alright, This was an unnecessarily difficult problem but I’ve managed to create a solution, that I’ll post here if anyone in the future ever finds this.

Note that in this code:

  • moveNode is the Vue Component to move
  • oldGrandParent is the ancestor of this parent that contains its prop definitions
  • newGrandParent is the equivalent ancestor this it is getting moved to
  • newParent is the immediate parent Vue Component that will hold it
// New data object
const newLayout = { x:0, y:0, w:moveNode.w * 2, h:moveNode.h, i:Date.now() };
// Remove VNode from old parent
const vNode = moveNode.$parent._vnode.children.splice(moveNode.$parent._vnode.children.indexOf(moveNode.$vnode), 1)[0];
// Rekey it
vNode.key = newLayout.i;
// Move HTMLElement
newParent._vnode.elm.appendChild(vNode.elm);
// Move VNode
newParent._vnode.children.push(vNode);
// Clean up old parent
moveNode.eventBus.$emit('dragEvent', 'dragend')
// Re-initialise Node for new parent (using copied source code - I don't think there's an easier way to do this)
this.rebindEventBus(moveNode,  Object.getOwnPropertyDescriptor(newParent, "eventBus"));
// Continue cleaning up old parent
moveNode.$parent.$children.splice(moveNode.$parent.$children.indexOf(moveNode), 1)
oldGrandParent.layout.splice(oldGrandParent.layout.findIndex(x => x.i == moveNode.i), 1);
// Give Vue instance new parent
moveNode.$parent = newParent;
// Add new data object to new parent, triggering reactivity
newGrandParent.layout.push(newLayout);
// Call Nodes "mounted" hook to finish re-parenting
this.$nextTick(function() { moveNode.$options.mounted.slice().reverse()[0].call(moveNode); });
// Reparenting complete!

Leave a comment