Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import { defineComponent, onMounted, onUnmounted } from '@vue/composition-api';
import Vue from 'vue';
export function vuenize(component: React.ComponentType, parentData: Vue.VNodeData = {}) {
const randomKey = 'key_' + Math.random();
let mountedNode: any = null;
return defineComponent({
name: component.name || component.displayName,
render(h) {
return h('div', { class: randomKey, ...parentData });
},
setup(props: any) {
onMounted(() => {
mountedNode = document.getElementsByClassName(randomKey)[0];
if (mountedNode) {
ReactDOM.render(React.createElement(component, props), mountedNode);
}
});
onUnmounted(() => {
if (mountedNode) ReactDOM.unmountComponentAtNode(mountedNode);
});
return {};
},
});
}
export function reactnize(component: any, parentProps: any) {
return (props: any) => {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (ref.current == null) return;
const App = Vue.extend(component);
const vm = new App({
el: ref.current,
props,
});
return () => vm.$destroy();
}, [ref.current, props]);
return React.createElement(
'div',
{
...parentProps,
},
React.createElement('div', { ref }),
);
};
}
/* How to use
import React from "react";
import {vuenize, reactnize}
function Foo() {
return <div>foo</div>
}
export default {
components: {
Foo: vuenize(Foo)
}
}
import ReactDOM from "react-dom";
import Bar from "./Bar.vue"
const ReactBar = reactnize(Bar);
ReactDOM.render(<ReactBar />)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment