Vue Transition结合多v-show使用问题:需保留插槽渲染数据
解决Vue Transition配合v-show多元素与插槽数据获取的冲突问题
核心思路
把过渡逻辑拆分为两层处理:
- 外层Transition负责骨架屏和内容容器的切换,用
v-if/v-else让两者互斥,确保同一时间仅一个元素处于Transition流程中 - 内容容器内部用
v-show控制业务内容和空状态的显示,保证插槽组件始终处于渲染状态,能正常发射数据
代码实现
<transition name="fade" mode="out-in"> <!-- 骨架屏:仅在加载状态显示,完成后销毁 --> <b-skeleton-table v-if="showSkeletons" key="skeleton" :rows="5" :columns="4" :table-props="{ bordered: true, striped: true }" /> <!-- 内容容器:始终渲染,确保插槽组件能正常触发事件 --> <div v-else key="content-container"> <div v-show="showPageContent"> <slot name="content" @row-count-change="handleRowCount" /> </div> <div v-show="showEmptyState"> <slot name="empty-state" /> </div> </div> </transition>
关键细节说明
- 外层
v-if/v-else:让骨架屏和内容容器互斥,完全符合Vue Transition只能处理单个元素进入/离开的要求,mode="out-in"保证骨架屏完全淡出后,内容容器再淡入。 - 内部
v-show:保留v-show避免插槽组件被销毁,确保能正常监听它发射的行数变化事件,从而更新showPageContent和showEmptyState的状态。 key属性:给Transition内的根元素添加key,帮助Vue准确识别元素身份,避免过渡逻辑出现异常。
可选优化:内容与空状态的过渡
如果需要业务内容和空状态之间也有淡入淡出效果,可以在内容容器内部再嵌套一层Transition:
<transition name="fade" mode="out-in"> <b-skeleton-table v-if="showSkeletons" key="skeleton" :rows="5" :columns="4" :table-props="{ bordered: true, striped: true }" /> <div v-else key="content-container"> <transition name="fade" mode="out-in"> <div v-show="showPageContent" key="content"> <slot name="content" @row-count-change="handleRowCount" /> </div> <div v-show="showEmptyState" key="empty"> <slot name="empty-state" /> </div> </transition> </div> </transition>
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

