在手动安装的Vue 3组件中传递Vuex存储

问题描述 投票:0回答:1

这个 Vue 2 解决方案是我一直用来手动安装 Vue 2 组件的方法,但是当我尝试将项目提升到 Vue 3 (使用兼容性构建进行迁移)时,我发现这种实例化和安装新组件将不再起作用。

我想知道是否有人有幸将这种手动安装组件的方法从 Vue 2 转换为 Vue 3 并遇到了这个问题。

这是我用于安装组件的 Vue 2 代码,使用“new”关键字并通过“propsData”传递 props,通过“store”传递 this$store。这在 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);
},

这是我使用 'mount-vue-component' 包安装组件的 Vue 3 代码。

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);
}

这里是我尝试实例化并挂载的组件,在挂载方法的两个示例中都已将其导入到父组件中

<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>

这里有两个警告 [Vue warn]:在渲染期间访问了属性“$store”,但未在实例上定义。[Vue warn]:执行渲染函数期间出现未处理的错误来自新安装的组件.

vuejs3 mount vuex4
1个回答
0
投票

经过几天的摸索找到了解决方案,如下所示

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);
© www.soinside.com 2019 - 2024. All rights reserved.