Reputation: 353
I'm working on a Laravel/InertiaJS/Vue3 project.
I have a Vue component that loads an iFrame which, in turn, loads an Inertiajs page.
When that InertiaJs page refreshes I want to sent a message to the parent component.
It seems the best way to do this is using postmessage()
router.visit(route('conversation.show',id),{
onSuccess: event =>{
window.top.postMessage('somemessage')
}
});
and a corresponding listener in the parent:
onMounted(() => {
window.addEventListener('message', methods.receiveMessage)
});
Before I continue with this, is there a more Inertia/Vue best-practise way to do this? e.g. using state management or some more secure way to communicate?
TIA
Upvotes: 0
Views: 259
Reputation: 353
In the end I wrote a little composable to post and listen to post messages:
import { onBeforeUnmount } from 'vue';
const tag = 'usePostMessage';
export const usePostMessage = () => {
//function to post a new message from the iframe
const postMessageFromIframe = (message, targetOrigin = window.top.location.origin) => {
window.top.postMessage({from: tag, payload : message}, targetOrigin);
};
//listen for messages from child frame
const listenToPostMessage = (actions, callback) => {
const messageHandler = (event) => {
//confirm message
if (event.source.origin === window.top.origin && event.data.from === tag) {
for (const action of actions){
if (action === event.data.payload.action){
callback(event.data.payload);
}
}
}
};
window.addEventListener('message', messageHandler);
// Cleanup the event listener when the component is unmounted
onBeforeUnmount(() => {
window.removeEventListener('message', messageHandler);
});
};
return { postMessageFromIframe, listenToPostMessage };
};
Then from inside the iframe:
const { postMessageFromIframe } = usePostMessage();
postMessageFromIframe({action:'resizeFrame'});
And outside the iframe:
const { listenToPostMessage } = usePostMessage();
listenToPostMessage(['mounted'],methods.onLoaded);
listenToPostMessage(['resizeFrame'],methods.adjustIframeSize);
Upvotes: 0