簡體   English   中英

Vuejs:根據路由有條件地渲染組件

[英]Vuejs : Rendering components conditionally based on route

某些組件需要為特定路由隱藏。 我能夠使用從這個 SO 問題中找到的路由更改觀察器來實現這一點 - Vuejs: Event on route change 我不想在 customizePage ( route - /customize )中顯示 header 和側邊欄。 但是當我從該特定頁面進行硬重新加載時會出現問題。 這不會執行手表,因此它會失敗。 我發現的解決方案是將它也放在mounted() 中,這樣它也可以在重新加載時執行。

但是在安裝和觀察器中具有相同的 function 看起來很奇怪。 有更好的方法嗎?

<template>
    <div>
        <TrialBanner v-if="$store.state.website.is_trial"/>
        <div class="page-body-wrapper" :class="{ 'p-0' : isCustomizePage}">
            <Sidebar :key="$store.state.user.is_admin" v-if="!isCustomizePage"/>
            <div class="main-panel" :class="{ 'm-0 w-100' : isCustomizePage}">
                <Header v-if="!isCustomizePage"/>
                <div class="content-wrapper" :class="{ 'p-0' : isCustomizePage}">
                    <router-view :key="$store.state.websiteId"></router-view>
                </div>
            </div>
        </div>
    </div>
</template>


mounted() {
  if(this.$route.path == '/customize') {
     this.isCustomizePage = true;
  } else {
     this.isCustomizePage = false;
  }
},
watch: {
  $route (to, from){
     if(this.$route.path == '/customize') {
       this.isCustomizePage = true;
     } else {
       this.isCustomizePage = false;
     }
  }
}

簡單修復:使用即時觀察者

watch: {
  $route: {
     immediate: true,
     handler(to, from) {
         if(this.$route.path == '/customize') {
           this.isCustomizePage = true;
         } else {
            this.isCustomizePage = false;
         }
     }
  }
}

更復雜但更可擴展的修復:使用“布局”組件。

演示

總體思路是創建“布局”組件,使用路由上的meta標記來定義每個路由的布局,然后在 App.vue 中使用動態組件來告訴應用使用哪個布局。

應用程序.vue

<template>
  <div id="app">    
    <component :is="layout">
      <router-view></router-view>
    </component>
  </div>
</template>

<script>

export default {
  name: "App",
  computed: {
    layout() {
      return this.$route.meta.layout || 'default-layout';
    }
  }
};
</script>

默認布局組件

<template>
    <div>
        <TrialBanner v-if="$store.state.website.is_trial"/>
        <div class="page-body-wrapper" >
            <Sidebar :key="$store.state.user.is_admin" />
            <div class="main-panel">
                <Header />
                <div class="content-wrapper">
                    <slot></slot>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
  name: 'DefaultLayout',
};
</script>

示例自定義頁面布局

<template>
    <div>
        <TrialBanner v-if="$store.state.website.is_trial"/>
        <div class="page-body-wrapper" class="p-0">
            <div class="main-panel" class="m-0 w-100">
                <div class="content-wrapper" class="p-0">
                    <slot></slot>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
  name: 'CustomizeLayout',
};
</script>

Main.js:將布局組件注冊為全局組件

import DefaultLayout from '@/layouts/DefaultLayout.vue';
import CustomizeLayout from '@/layouts/CustomizeLayout.vue';

Vue.component('default-layout', DefaultLayout);
Vue.component('customize-layout', CustomizeLayout);

Router.js:路由定義每個路由的布局

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView,    
  },
  {
    path: '/customize',
    name: 'customize',
    component: CustomizeView,
    meta: {
      layout: 'customize-layout'
    }
  }
];

每個布局組件中的<slot></slot>是 View 將呈現的位置。 如果您想在每個布局的區域中呈現不同的components ,您還可以擁有多個命名插槽命名視圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM