Use the same format as React.createElement for VueInjector.createReactElement

Allows props to flow down to Vue components cleanly
This commit is contained in:
Samuel Elliott 2018-05-29 21:47:44 +01:00
parent 4654025423
commit 68d4617e46
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
3 changed files with 26 additions and 28 deletions

View File

@ -121,10 +121,10 @@ export default new class EmoteModule {
text = null;
}
newMarkup.push(VueInjector.createReactElement({
components: { EmoteComponent },
data: { emote, hasWrapper: /;[\w]+;/gmi.test(word) },
template: '<EmoteComponent :src="emote.src" :name="emote.name" :hasWrapper="hasWrapper" />'
newMarkup.push(VueInjector.createReactElement(EmoteComponent, {
src: emote.src,
name: emote.name,
hasWrapper: /;[\w]+;/gmi.test(word)
}));
continue;
@ -211,10 +211,7 @@ export default new class EmoteModule {
this.unpatchChannelTextArea = MonkeyPatch('BD:ReactComponents', ChannelTextArea.component.prototype).after('render', (component, args, retVal) => {
if (!(retVal.props.children instanceof Array)) retVal.props.children = [retVal.props.children];
retVal.props.children.splice(0, 0, VueInjector.createReactElement({
components: { Autocomplete },
template: '<Autocomplete />'
}, true));
retVal.props.children.splice(0, 0, VueInjector.createReactElement(Autocomplete, {}, true));
});
for (const e of document.querySelectorAll(selector)) {

View File

@ -48,11 +48,7 @@ export default class extends Module {
const username = ReactHelpers.findByProp(retVal, 'type', 'h2');
if (!username) return;
username.props.children.splice(1, 0, VueInjector.createReactElement({
components: { BdMessageBadge },
data: { c },
template: '<BdMessageBadge :developer="c.developer" :webdev="c.webdev" :contributor="c.contributor" />'
}));
username.props.children.splice(1, 0, VueInjector.createReactElement(BdMessageBadge, c));
});
// Rerender all messages
@ -111,11 +107,7 @@ export default class extends Module {
const c = contributors.find(c => c.id === user.id);
if (!c) return;
retVal.props.children.splice(1, 0, VueInjector.createReactElement({
components: { BdMessageBadge },
data: { c },
template: '<BdMessageBadge :developer="c.developer" :webdev="c.webdev" :contributor="c.contributor" />'
}));
retVal.props.children.splice(1, 0, VueInjector.createReactElement(BdMessageBadge, c));
} catch (err) {
Logger.err('ProfileBadges', ['Error thrown while rendering a NameTag', err]);
}
@ -147,11 +139,7 @@ export default class extends Module {
const c = contributors.find(c => c.id === user.id);
if (!c) return;
const element = VueInjector.createReactElement({
components: { BdBadge },
data: { c },
template: '<BdBadge :developer="c.developer" :webdev="c.webdev" :contributor="c.contributor" />',
});
const element = VueInjector.createReactElement(BdBadge, c);
if (!retVal) {
setRetVal(ReactHelpers.React.createElement('div', {

View File

@ -31,13 +31,14 @@ export default class {
/**
* Returns a React element that will render a Vue component.
* @param {Object} options Options to pass to Vue
* @param {Object} component A Vue component to render
* @param {Object} props Props to pass to the Vue component
* @param {Boolean} mountAtTop Whether to mount the Vue component at the top of the React component instead of mounting it in a container
* @return {React.Element}
*/
static createReactElement(options, mountAtTop) {
static createReactElement(component, props, mountAtTop) {
const React = WebpackModules.getModuleByName('React');
return React.createElement(this.ReactCompatibility, {options, mountAtTop});
return React.createElement(this.ReactCompatibility, {component, mountAtTop, props});
}
static get ReactCompatibility() {
@ -55,7 +56,12 @@ export default class {
this.vueInstance.$mount(this.vueMount);
}
componentDidUpdate() {
componentDidUpdate(oldProps) {
if (oldProps.options && !this.props.options || !oldProps.options && this.props.options) {
this.vueInstance.$destroy();
delete this._vueInstance;
}
this.vueInstance.$mount(this.vueMount);
}
@ -75,7 +81,14 @@ export default class {
}
get vueInstance() {
return this._vueInstance || (this._vueInstance = new Vue(this.props.options));
return this._vueInstance || (this._vueInstance = new Vue(this.props.options || {
data: this.props,
render(createElement) {
return createElement(this.component, {
props: this.props
});
}
}));
}
}
}