This Vue 2 solution was what I have been using to mount a Vue 2 component manually, but as I am trying to uplift the project to Vue 3 (using a compatibility build for migration) I am finding that this method of instantiating and mounting a new component won't work anymore.
I am wondering if anyone has had any luck converting this method of manual mounting components from Vue 2 to Vue 3 and have come across this issue.
Here is my Vue 2 code for mounting the component, using the 'new' keyword and passing props with 'propsData' and this$store with 'store'. This worked great in Vue 2.
mountLegendGroup (legendElement, indicators, panel) {
const Component = LegendGroup;
const legendGroup = new Component({
propsData: {
indicators: indicators.map(i => i.params),
isUpper: panel.isUpper,panelUid:
panel.params.uid
},
store: this.$store
});
legendElement.innerHTML = '';
legendGroup.$mount(legendElement, true);
},
Here is my Vue 3 code for mounting the component, using the 'mount-vue-component' package.
mountLegendGroup (legendElement, indicators, panel) {
const Component = LegendGroup;
Component.props = ['indicators', 'isUpper', 'panelUid'];
legendElement.innerHTML = '';
mount(Component, {
props: {
'indicators': indicators.map(i => i.params),
'isUpper': panel.isUpper,
'panelUid': panel.params.uid
}
}, legendElement);
}
Here is the component I am trying to instantiate and mount, which has been imported in the parent component in both examples of the mounting method
<template>
<div>
<div class="legend-group">
<div class="left-group">
<div
v-for="(indicator, index) in indicators"
:key="index"
>
<LegendItem
:key="index"
:indicator="indicator"
:panel-uid="panelUid"
/>
</div>
</div>
<div class="right-group">
<LegendMovePanel
v-if="isMovable"
:panel-uid="panelUid"
/>
<LegendExpandCollapse
v-if="showExpandCollapse"
:panel-uid="panelUid"
/>
<LowerOverlayDropdown
v-if="!isUpper"
:panel-uid="panelUid"
/>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import LegendExpandCollapse from '@/components/modcharts/LegendExpandCollapse';
import LegendItem from '@/components/modcharts/LegendItem';
import LegendMovePanel from '@/components/modcharts/LegendMovePanel';
import LowerOverlayDropdown from '@/components/modcharts/LowerOverlayDropdown';
export default {
components: {
LegendExpandCollapse,
LegendItem,
LegendMovePanel,
LowerOverlayDropdown
},
computed: {
...mapGetters([
'activeTheme',
'chartGetter',
'options'
]),
isMovable () {
const chart = this.chartGetter();
return !this.isUpper && chart.panels.length > 2;
},
panelComputedHeightsEnabled () {
return this.options.usePanelComputedHeight;
},
resizablePanelsEnabled () {
return this.options.panelResize;
},
showExpandCollapse () {
return (
!this.isUpper &&
!this.panelComputedHeightsEnabled &&
!this.resizablePanelsEnabled
);
}
},
props: {
indicators: {
type: Array,
required: true
},
isUpper: {
type: Boolean,
default: false
},
panelUid: {
type: String,
required: true
}
}
};
</script>
Here are the two warnings [Vue warn]: Property "$store" was accessed during render but is not defined on instance. and [Vue warn]: Unhandled error during execution of render function coming from the newly mounted component.
Found the solution after a couple of days of poking around, seen below
const legendGroup = createApp({
render () {
return h(LegendGroup, {
indicators: indicators.map(i => i.params),
isUpper: panel.isUpper,
panelUid: panel.params.uid
});
}
});
legendGroup.use(this.$store);
legendElement.innerHTML = '';
legendGroup.mount(legendElement, true);