微信小程序中,不同的分包对应不同的下载单元;因此,除了非独立分包可以依赖主包外,分包之间不能互相使用自定义组件或进行 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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。