# Routing / URL Handling

State Management

# Auflösen von Routen

Da hubble's Architektur auf der von NuxtJS basiert, erfolgt die Konfiguration von Routen über das Einhalten der Ordner Struktur (opens new window), die NuxtJS vorgibt. Somit ist keine separate Datei und manuelle Konfiguration notwendig, um ein Mapping zwischen den anzuzeigenden Komponenten und URLs anzugeben.

Dabei gibt es zwei verschiedene Arten von Routen in hubble, die sich aus den Dateien im ~/pages Ordner ergeben. Zum einen statische Routen wie z.B. ~/pages/checkout/cart.vue für den Warenkorb und zum anderen dynamische Routen für z.B. die Produktdetailseite, Kategorien oder CMS Seiten. Diese sind dynamisch, weil zum Zeitpunkt des Seitenaufrufs nicht feststeht, um welche Entität (Produkt, Kategorie, etc.) es sich handelt. Dynamische Routen werden von der ~/pages/_.vue aufgelöst.

Außerdem definieren Seiten ein Layout, in dessen Markup der eigentliche Inhalt der Route eingebettet wird. Dies bietet eine Möglichkeit auf mehreren Seiten verwendete Elemente wie Menü, Logos und Footer einzubinden. In dem Abschnitt Layouts erfahren Sie mehr über die in hubble verfügbaren Layouts.

Der Grundaufbau einer Seite lässt sich gut anhand der Home Page ~/pages/index.vue ableiten. Dieser setzt sich aus den Properties name, layout und middleware zusammen:



 
 
 





 



// ~/pages/index.vue 
export default {
    name: 'Index',
    layout: 'hubble',
    middleware: [
        'apiIndexRoute',
        'apiAuthenticate',
        'apiLocalization',
        'apiResourceMenu',
        'trackClickPath'
    ],
    // ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
# Mehr Erfahren

Um mehr über State Management und zur Verwendungsweise von Vuex in hubble zu erfahren kann der Abschnitt State Management der Dokumentation referenziert werden.

# Beispiel: Auflösen von dynamischen Routen

Die Middleware apiResourceRoute übergibt zunächst die angefragte URL an den Endpunkt /api/json/urls/:

// ~/pages/_.vue
middleware: [
    ...
    'apiResourceRoute',
    ...
],
1
2
3
4
5
6

Diese delegiert API Requests an den Vuex Store:

// ~/modules/@hubblecommerce/hubble/core/middleware/api/apiResourceRoute.js
store.dispatch('apiCall', {
    action: 'get',
    tokenType: 'api',
    apiType: 'data',
    endpoint: _.join(['/api/json/urls/', path], '')
}, { root: true })
.then((response) => {
    // Throw 404 page if url is not known
    if (_.isEmpty(response.data.result.item)) {
        error({statusCode: 404, message: 'Unknown URL'});
        resolve('UriResolver OK');
        return false;
    }

    // Get resource by id from api and set matching pageview component
    store.dispatch('modApiResources/apiResolveUriData', {
        data: response.data,
        query: route.query
    })
    .then(() => {
        resolve('UriResolver OK')
    })
    .catch(() => {
        reject()
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Dieser liefert dann den Seitentypen bzw. die Entität zurück um die es sich handelt. Gleichzeitig werden von der API alle relevanten Daten bezüglich der Entität bezogen (modApiResources/apiResolveUriData).

Die Seite ~/pages/_.vue kann nun anhand des Pagetypes und der Daten der Entität die Seite rendern:

<!-- ~/pages/_.vue -->
<component :is="currentComponent" v-if="pageType !== null" />
1
2

# Beispiel: Zusammenhang zwischen Middleware & Menü

Das Menü ist Teil der meisten Seiten, was bedeutet, jene Seiten haben die Middleware apiResourceMenu in ihrer middleware Property aufgelistet. Es ist also in diesem Fall Aufgabe der Middleware apiResourceMenu die Menüdaten bereitzustellen, bevor die Seite gerendert werden kann.

# Hauptschritte (vereinfacht):

  • Schritt 1: Middleware einer Route wird aufgerufen






 





// ~/pages/_.vue
export default {
    name: 'RouteResolver',
    layout: 'hubble',
    middleware: [
        // ...
        'apiResourceMenu',
        // ...
    ],
    // ..
}
1
2
3
4
5
6
7
8
9
10
11
  • Schritt 2: Middleware führt Action eines Vuex Store Modules aus
// ~/modules/@hubblecommerce/hubble/core/middleware/apiResourceMenu.js
// ...
store.dispatch('modApiMenu/getMenu', {})
// ...
1
2
3
4
  • Schritt 3: Vuex Store Modul Action bezieht Daten von API Endpunkt


 

 



 




 










// ~/modules/@hubblecommerce/hubble/core/store/api/modApiMenu/getMenu.js
actions: {
    async getMenu({ commit, dispatch }) {
        return new Promise(function(resolve, reject) {
            dispatch('apiCall', {
                action: 'get',
                tokenType: 'api',
                apiType: 'data',
                endpoint: '/api/json/menu/children',
                params: {
                    _size: 30
                }
            }, { root: true })
            .then((response) => {
                commit('setDataMenu', {
                    data: response.data
                });
                // ... 
            })
            // ...
        });
    }
} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • Schritt 4: layouts/hubble.vue

Nachdem die API Response in dem benötigten Format im Vuex State gespeichert wurde, kann die layouts/hubble.vue, welche für das Rendering des Menüs verantwortlich ist, auf diese Daten zugreifen:

// ~/layouts/hubble.vue
computed: {
   ...mapState({
        dataMenu: state => state.modApiMenu.dataMenu
   })
}
1
2
3
4
5
6

Den Unterkomponenten des Layouts können dann als Properties diese Daten übergeben werden:

<!-- ~/layouts/hubble.vue -->
<the-mega-menu v-if="!isEmpty(dataMenu)" :data-items="dataMenu" />
1
2

# Möglichkeiten zur Navigation zwischen Routen

Durch die Navigationsmöglichkeiten in NuxtJS ergeben sich folgende für hubble: Zum einen ist es möglich die <nuxt-link> Komponente zu verwenden, für die bei Bedarf auch Prefetching global oder lokal, je Link, aktiviert werden kann. Mehr zu Prefetching unter Prefetching.

Außerhalb von Templates wird Vue Router this.$router verwendet für Weiterleitungen. Diese Variante eignet sich, wenn es diverser Vorprüfungen oder Vorkalkulationen bedarf, bevor eine entsprechende Weiterleitung stattfinden kann. Im Folgenden ist dazu ein einfaches Beispiel aus dem Overlay Menü der Wunschliste, welches in hubble als offCanvas bekannt ist, zu sehen:

// ~/components/customer/WishlistLayer.vue
methods: {
    checkoutWishlist: function() {
        this.hideMenu();
    
        this.$router.push({
            path: this.localePath('customer-wishlist')
        });
    }
}
1
2
3
4
5
6
7
8
9
10

Obiger push auf 'customer-wishlist' führt auf die Seite http://localhost:3336/customer/wishlist.

Der dazugehörige Template Ausschnitt, welcher zum Aufruf der Methode führt, sieht wie folgt aus:

<button v-if="qty > 0"
        class="wishlist-button button-primary"
        @click.prevent="checkoutWishlist()"
>
    {{ $t('Go to wishlist') }}

    <material-ripple />
</button>
1
2
3
4
5
6
7
8