1
头图

微信小程序中,不同的分包对应不同的下载单元;因此,除了非独立分包可以依赖主包外,分包之间不能互相使用自定义组件或进行 require。「分包异步化」特性将允许通过一些配置和新的接口,使部分跨分包的内容可以等待下载后异步使用,从而一定程度上解决这个限制。

口述表达就是,如果想要在一个分包内使用另一个分包的组件或资源,可以通过分包异步化实现。
通过分包异步化,可以节省包大小,当你的主包或子包的大小接近2M时,新的资源可以通过分包异步化引入,异步化组件不会占用包大小,从而节省包空间。

配置pages.json

{
    "pages": [ // https://uniapp.dcloud.io/collocation/pages
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "首页",
                "navigationStyle": "custom",
                "navigationBarTextStyle": "white" 
            }
        }
    ],
    "subPackages": [
        {
            "root": "subPackages/agent",
            "pages": [{
                "path": "pages/agent/index",
                "style": {
                    "navigationBarTitleText": "智能体页面",
                    "navigationBarTextStyle": "black",
                    "usingComponents": {
                        "nav-bar": "/subPackages/chat-component/pages/nav-bar/index" // 组件的路径
                    },
                    "componentPlaceholder": {
                        "nav-bar": "view" // 未完成时的占位组件
                    }
                }
            }]
        },
        {
            "root": "subPackages/chat-component",
            "pages": [{
                "path": "pages/chat/index",
                "style": {
                    "navigationBarTitleText": "",
                    "navigationStyle": "custom",
                    "navigationBarTextStyle": "white"
                }
            }]
        }
    ],
}

这里我样式了一个子包中使用分包异步化,加载另一个子包组件的例子,其中subPackages/agent是一个子包,subPackages/chat-component是另一个子包,我在subPackages/agent子包的pages/agent/index页面引入subPackages/chat-component子包内的nav-bar组件

由于我引入的是chat-component子包内的nav-bar/index页面,而我们在pages.json里只定义了chat-component/pages/chat/index.vue页面,所以我们必须在chat/index.vue内引入同包的nav-bar/index.vue页面,否则/nav-bar/index.vue将不会被打包,导致分包异步化导入失败

<template>
    <view>
        <NavBar/>
    </view>
</template>

<script setup>
import NavBar from '@/subPackages/chat-component/pages/nav-bar/index.vue';
</script>

到这里,我们的异步化的配置工作就做好了,可以在agent/index.vue页面正常导入了

导入分包异步化组件

agent/index.vue页面

<template>
    <view>
        <NavBar />
    </view>
</template>

<script setup>
import NavBar from '@/subPackages/chat-component/pages/nav-bar/index.vue';
</script>

就像正常引入组件一样,导入使用即可,需要注意,导入的路径得跟pages.json内配置的组件路径一致。

分包异步化支持的组件通信

经过测试,得到如下总结:
支持的通信方式:

  • emit
  • props
  • defineModel
  • provide/inject

不支持的通信方式:

  • defineExpose 父组件调用异步化组件内的事件

下面是测试页面,你可以复制到你的页面里直接查看效果
父组件 agent/index.vue

<template>
    <view>
        <view>父级页面</view>
        <button type="primary" size="mini" @click="onFn">父组件调用子组件事件</button>
        <button type="primary" size="mini" @click="onFnUpdate">父组件修改双向绑定内容</button>
        <view>===============================================</view>
        <view>分包异步化组件</view>
        <NavBar ref="navBarRef" :text="text" v-model="text2" @onBack="onBack" />
    </view>
</template>

<script setup>
import NavBar from '@/subPackages/chat-component/pages/nav-bar/index.vue';
import { ref, provide } from 'vue';

const navBarRef = ref();

const form = ref({
    text: '测试provide'
});
provide('form', form);

const text = ref('父组件内容');

const text2 = ref('双向绑定的内容');
const onFnUpdate = () => {
    text2.value = '父组件修改';
};

const onFn = () => {
    navBarRef.value.event1();
};

const onBack = (e) => {
    console.log('子组件返回了', e);
};
</script>

异步化组件 nav-bar/index.vue

<template>
    <view>
        <button type="primary" size="mini" @click="onBack">子组件事件回传</button>
        <view>props绑定内容:{{ props.text }}</view>
        <button type="primary" size="mini" @click="onUpdate">子组件修改双向绑定内容</button>
        <view>
            {{ text2 }}
        </view>
        <view>
            {{ form.text }}
        </view>
    </view>
</template>

<script setup>
import { defineEmits, defineProps, defineExpose, defineModel, inject } from 'vue';

const props = defineProps({
    text: {
        type: String,
        defaule: ''
    }
});
const emit = defineEmits(['onBack']);

const form = inject('form');

const text2 = defineModel();
const onUpdate = () => {
    text2.value = '子组件修改';
};

const onBack = () => {
    emit('onBack', { text: '子组件返回' });
};

const event1 = () => {
    console.log('子组件内事件');
};

defineExpose({ event1 });
</script>

参考文档:
微信小程序分包异步化
如何使用分包异步化能力?
uniapp微信小程序之分包异步化


兔子先森
710 声望1.1k 粉丝

致力于新技术的推广与优秀技术的普及。