Некоторые компоненты необходимо скрыть для определенных маршрутов. Мне удалось добиться этого с помощью наблюдателя для изменения маршрута, найденного из этого вопроса SO - Vuejs: событие на маршруте изменить. Я не хочу отображать заголовок и боковую панель в customizePage (route - / customize). Но возникает проблема, когда я выполняю жесткую перезагрузку с этой конкретной страницы. Это не выполняет часы и, следовательно, они не работают. Решение, которое я нашел, заключалось в том, что он также был в установленном (), поэтому он запускается также при перезагрузке.

Но наличие одной и той же функции в mount и watcher выглядит странно. Есть ли способ лучше?

<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;
     }
  }
}
0
theFrontEndDev 16 Июл 2020 в 17:11

1 ответ

Лучший ответ

Простое исправление: Используйте немедленного наблюдателя

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

Более сложное, но более расширяемое исправление: Используйте «макетные» компоненты.

Демо

Общая идея состоит в том, чтобы создать компоненты «Макет», использовать тег meta на маршрутах для определения макетов для каждого маршрута, а затем использовать динамический компонент в App.vue, чтобы сообщить приложению, какой макет использовать.

App.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> в каждом компоненте макета - это место, где будет отображаться представление. У вас также может быть несколько именованных слотов и именованные представления, если вы хотите отображать разные components в областях для каждого макета.

1
Steven B. 16 Июл 2020 в 14:55