uni-app 使用作用域插槽的组件放在另一个组件的slot里出现的问题
uni-app 使用作用域插槽的组件放在另一个组件的slot里出现的问题
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | win10 | HBuilderX |
产品分类:uniapp/小程序/微信
示例代码:
// /components/test/test.vue,使用了作用域插槽
<template>
<view>
<slot name="list" :slotList="list"></slot>
</view>
</template>
<script>
export default {
name:"test",
props: {
list: {
type: Array
}
},
data() {
return {
}
}
}
</script>
// /components/other/other.vue,普通组件
<template>
<view><slot></slot></view>
</template>
<script>
export default {
name: 'other',
data() {
return {}
}
}
</script>
// /pages/test/test.vue,测试页面
<template>
<view>
<!-- 放在外层的test组件 -->
<test :list="[1, 2, 3, 4, 5, 6]">
<template #list="{ slotList }">
<view v-for="(item, index) in slotList" :key="index" [@click](/user/click)="test">{{ item }}</view>
</template>
</test>
<!-- 放在另外一个组件的slot中的test组件 -->
<other>
<test :list="[11, 22, 33, 44, 55, 66]">
<template #list="{ slotList }">
<view v-for="(item, index) in slotList" :key="index" [@click](/user/click)="test">{{ item }}</view>
</template>
</test>
</other>
</view>
</template>
<script>
export default {
data() {
return {}
},
methods: {
test() {
console.log('test')
}
}
}
</script>
操作步骤:
运行示例代码
预期结果:
2个test组件均能正常解析
实际结果:
只有第1个test正常解析,第2个test未显示出来,将第2个test中的@click事件取消,则正常显示出来了。
bug描述:
如下示例代码,测试页面中,一个test组件放在根下,另一个test组件放在other组件中,第一个test正常显示了内容,第二个test未显示,将第二个test中的@click取消,则正常显示。以上是微信小程序测试结果,H5中都正常显示出来了。
更多关于uni-app 使用作用域插槽的组件放在另一个组件的slot里出现的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
问题已确认,已加分,后续会优化。
临时解决方案:
manifest.json中配置如下:
scopedSlotsCompiler:legacy 详情
更多关于uni-app 使用作用域插槽的组件放在另一个组件的slot里出现的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
HBuilderX alpha 3.1.22+ 已修复
这是一个微信小程序平台特有的作用域插槽限制问题。在微信小程序中,当作用域插槽组件被嵌套在另一个组件的slot中时,事件绑定会导致渲染异常。
问题核心在于微信小程序的渲染机制:作用域插槽在跨组件层级传递时,事件处理函数的作用域链可能被中断。当组件被放置在另一个组件的slot中,且该slot内容包含作用域插槽时,事件绑定会干扰小程序的虚拟DOM diff算法。
解决方案:
- 移除嵌套结构:尽量避免将作用域插槽组件放在其他组件的slot中
- 使用事件代理:在父组件中处理点击事件
- 改用props传递事件处理函数:
// test组件修改
<template>
<view>
<slot name="list" :slotList="list" :onItemClick="onItemClick"></slot>
</view>
</template>
<script>
export default {
props: {
list: Array,
onItemClick: Function
}
}
</script>
// 页面中使用
<other>
<test :list="[11, 22, 33, 44, 55, 66]" :onItemClick="test">
<template #list="{ slotList, onItemClick }">
<view v-for="(item, index) in slotList" :key="index"
@click="() => onItemClick(item)">{{ item }}</view>
</template>
</test>
</other>

