Vue中如何根据条件优雅实现布局的动态切换渲染?
布局条件渲染的优雅实现方案
当然可以实现,完全不需要重复维护两份相同的组件内容,下面两种方案都能达到和v-if/v-else一致的渲染效果(不满足条件的布局不会被挂载,无冗余DOM),同时避免代码重复:
方案1:使用内置动态组件(优先推荐)
直接用 Vue 内置的 <component> 动态组件,通过 is 属性绑定当前要渲染的布局组件,内部的插槽内容只需要写一次,两个布局会自动透传插槽内容:
<script setup> import { ref } from 'vue' import LayoutA from './LayoutA.vue' import LayoutB from './LayoutB.vue' // 你的布局切换判断条件 const useLayoutA = ref(true) </script> <template> <component :is="useLayoutA ? LayoutA : LayoutB"> <!-- 组件内容只写这一次即可 --> // component contents </component> </template>
如果不同布局需要接收不同的参数,可以结合计算属性动态绑定props:
<script setup> import { ref, computed } from 'vue' import LayoutA from './LayoutA.vue' import LayoutB from './LayoutB.vue' const useLayoutA = ref(true) const currentLayout = computed(() => useLayoutA.value ? LayoutA : LayoutB) const layoutProps = computed(() => useLayoutA.value ? { navTheme: 'dark' } // LayoutA 接收的参数 : { showSidebar: true } // LayoutB 接收的参数 ) </script> <template> <component :is="currentLayout" v-bind="layoutProps"> // component contents </component> </template>
方案2:抽离通用布局切换包装器
如果项目里多个页面都需要做同类布局切换,可以把切换逻辑抽成独立的包装组件,后续所有业务页面直接复用就行:
<!-- components/LayoutSwitcher.vue --> <template> <LayoutA v-if="useLayoutA"><slot /></LayoutA> <LayoutB v-else><slot /></LayoutB> </template> <script setup> import LayoutA from './LayoutA.vue' import LayoutB from './LayoutB.vue' defineProps({ useLayoutA: { type: Boolean, default: true } }) </script>
业务页面使用时不需要关心布局切换逻辑,直接写自身内容即可:
<template> <LayoutSwitcher :use-layout-a="condition"> // component contents </LayoutSwitcher> </template>
注意:不要用
v-show做布局切换,v-show会把两个布局的DOM(比如你示例里的v-nav、v-footer)都渲染出来,只是通过CSS控制显隐,会产生冗余节点,造成不必要的性能开销。
内容的提问来源于stack exchange,提问作者Artur Müller Romanov
相关产品推荐
相关产品推荐

