uni-app 子组件的具名插槽如果延迟渲染的话,样式会丢失
uni-app 子组件的具名插槽如果延迟渲染的话,样式会丢失
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Mac | macOS Ventura版本13.6.3 | CLI 2.0.2-3090920231225001 |
产品分类:uniapp/H5
### 示例代码:
```javascript
// 子组件
<template>
<view class="card">
<view>我是子组件</view>
<view class="title" v-if="$slots.title">
<slot name="title"></slot>
</view>
<slot/>
<view class="footer" v-if="$slots.footer">
<slot name="footer"></slot>
</view>
</view>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
.card {
border: 2upx solid #000;
margin-bottom: 20upx;
.title {
color: red;
}
.footer {
color: blue;
}
}
</style>
// 父组件
<template>
<view>
<childComponent>
<template v-if="step === 1">
<view>我是步骤1的内容</view>
</template>
<template v-if="step === 2">
<view slot="title">我是步骤2的标题,我是红色的</view>
<view>我是步骤2的内容</view>
<view slot="footer">我是步骤2的FOOTER</view>
</template>
</childComponent>
</view>
</template>
<script>
import childComponent from './_components/childComponent.vue'
export default {
components: {
childComponent
},
data() {
return {
step: 1
}
},
mounted() {
setTimeout(() => {
this.step = 2;
}, 3000);
}
}
</script>
<style>
</style>
操作步骤:
代码复制粘贴至项目中,页面自动运行
预期结果:
title是红色字体,内容是黑色字体,Footer是蓝色字体
实际结果:
title是黑色字体,内容是黑色字体,Footer是蓝色字体
bug描述:
子组件的具名插槽title如果延迟渲染的话,title的样式会丢失,但是footer没问题
更多关于uni-app 子组件的具名插槽如果延迟渲染的话,样式会丢失的实战教程也可以访问 https://www.itying.com/category-93-b0.html
3 回复
子组件去掉 v-if 判断
<template>
<view class="card">
<view>我是子组件</view>
<view class="title">
<slot name="title"></slot>
</view>
<slot />
<view class="footer">
<slot name="footer"></slot>
</view>
</view>
</template>
更多关于uni-app 子组件的具名插槽如果延迟渲染的话,样式会丢失的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在 uni-app 中,如果你在子组件中使用具名插槽(Named Slot),并且延迟渲染(例如通过 v-if 或 v-show 控制),可能会出现样式丢失的问题。这通常是由于以下原因导致的:
1. 样式作用域问题
- 如果你在子组件中使用了
scoped样式,样式可能会被限制在子组件的范围内。当插槽内容延迟渲染时,这些样式可能无法正确应用到插槽内容上。 - 解决方案:可以使用
::v-deep或/deep/来穿透作用域样式,确保样式能够应用到插槽内容。
/* 子组件样式 */
.child-component ::v-deep .slot-content {
color: red;
}
2. 样式未正确加载
- 如果插槽内容是通过异步加载的(例如通过
v-if或v-show),样式可能没有在正确的时间被加载。 - 解决方案:确保样式在插槽内容渲染时已经加载。你可以使用
v-if而不是v-show,或者在插槽内容渲染后手动触发样式更新。
3. 样式优先级问题
- 延迟渲染的内容可能会导致样式优先级问题,特别是当父组件和子组件都有相同类名的样式时。
- 解决方案:确保样式的优先级正确,或者使用更具体的类名来避免冲突。
4. 重新渲染问题
- 如果插槽内容在延迟渲染后重新渲染,可能会导致样式丢失。
- 解决方案:确保插槽内容在重新渲染时样式能够正确应用,或者使用
key属性强制重新渲染。
5. 使用 v-show 的问题
v-show只是通过display: none来隐藏元素,而不会重新渲染。这可能会导致样式在元素显示时未正确应用。- 解决方案:使用
v-if而不是v-show,这样可以确保元素在显示时重新渲染并应用样式。
示例代码
<!-- 子组件 -->
<template>
<div class="child-component">
<slot name="content"></slot>
</div>
</template>
<style scoped>
.child-component ::v-deep .slot-content {
color: red;
}
</style>
<!-- 父组件 -->
<template>
<child-component>
<template v-slot:content>
<div v-if="showContent" class="slot-content">
这是插槽内容
</div>
</template>
</child-component>
</template>
<script>
export default {
data() {
return {
showContent: false
};
},
mounted() {
setTimeout(() => {
this.showContent = true;
}, 1000);
}
};
</script>


