diff --git a/client/src/builtin/EmoteModule.js b/client/src/builtin/EmoteModule.js index bed5d57b..feefe78a 100644 --- a/client/src/builtin/EmoteModule.js +++ b/client/src/builtin/EmoteModule.js @@ -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: '' + 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: '' - }, true)); + retVal.props.children.splice(0, 0, VueInjector.createReactElement(Autocomplete, {}, true)); }); for (const e of document.querySelectorAll(selector)) { diff --git a/client/src/ui/profilebadges.js b/client/src/ui/profilebadges.js index 06a62ac3..fc585ecf 100644 --- a/client/src/ui/profilebadges.js +++ b/client/src/ui/profilebadges.js @@ -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: '' - })); + 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: '' - })); + 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: '', - }); + const element = VueInjector.createReactElement(BdBadge, c); if (!retVal) { setRetVal(ReactHelpers.React.createElement('div', { diff --git a/client/src/ui/vueinjector.js b/client/src/ui/vueinjector.js index dd1e5b14..0523d434 100644 --- a/client/src/ui/vueinjector.js +++ b/client/src/ui/vueinjector.js @@ -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 + }); + } + })); } } }