HTML5-Tutorium: JavaScript: Hello World Vue 06

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg

Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:

Korrektheit: 3
(zu größeren Teilen überprüft)
Umfang: 4
(unwichtige Fakten fehlen)
Quellenangaben: 3
(wichtige Quellen vorhanden)
Quellenarten: 5
(ausgezeichnet)
Konformität: 3
(gut)

Vorlesung WebProg

Inhalt | Teil 1 | Teil 2 | Teil 3 | Teil 4 | Teil 5 | Teil 6 | Vue 1 | Vue 2 | Vue 3 | Vue 4 | Vue 5 | Vue 6

Vorlage:InBearbeitung

Musterlösung
Git-Repository, git checkout v06, git checkout v06a, git checkout v06b (JavaScript)
Git-Repository (TypeScript), git checkout v06

Anwendungsfälle (Use Cases)

Die Version des fünften Teils des Vue-Tutoriums wird so geändert, dass die Sprache zur Laufzeit geändert werden kann.

Zunächst wird jedoch eine Navigationskomponente eingeführt. Dies hat den Zweck, das Routing an einem Beispiel zu erklären.

Aufgabe

Aufgabe: Konfigurieren und internationalisieren Sie die Anwendung mit Hilfe von dynamischen JSON-Dateien.

Erstellen eines neuen Projektzweigs

Erstellen Sie einen neuen Projektzweig (branch) innerhalb von hello_world_vue und fügen Sie das Package uuid hinzu:

git checkout v05b     # Wechsle in den Branch v05b
git checkout -b v06  # Klone v05b in einen neuen Branch v06
npm i

Views

Anstelle von Sections werden Views verwendet. Dazu werden die Section-Komponenten in den Ordner View verschoben und umbenannt:

src/view/ViewHello.vue
src/view/ViewHome.vue     // an Stelle von ViewQuestion.vue

src/view/ViewError404.vue // neu

ViewQuestion.vue wird in ViewHome.vue unbenannt, da diese Seite als Startseite verwendet wird.

Zusätzlich wird eine Seite Vue404.vue angelegt, die immer dann ausgeliefert wird, wenn der Benutzer auf eine URL zugreift, der keine View-Datei zugeordnet ist.

Die SCSS-Dateien sollten analog umbenannt und unter den neuen Namen importiert werden. Für ViewError404.vue muss natürlich auch eine SCSS-Datei angelegt werden. Diese verweist allerdings nur auf _View.scss.

<!-- src/view/ViewError404.vue -->

<script setup>
  import router    from '@/router'
  import storeI18n from '@/store/StoreI18n'

  const phrases = storeI18n().phrases
</script>

<template>
  <h1>404</h1>
  <p>{{phrases.pageNotFound.replace('$1', router.currentRoute.value.path)}}</p>
</template>

<style scoped lang="scss">
  @import '/css/view/ViewError404';
</style>

Router-Plugin

Um mit Vue Multipage-Anwendungen realisieren zu können, benötigt man das Router-Plugin.

// src/main.js

import { createPinia } from 'pinia'
import { createApp }   from 'vue'
import getJson         from '@/service/getJson'
import router          from './router'
import App             from './App.vue'
const
  pinia   = createPinia(),
  app     = createApp(App),
  init    = async () =>
            { const
                config = await getJson('/json/config.json')
        
              config.i18n =
                await getJson(config.apiRoot.replace
                              ('$1',
                                config.defaultLanguage
                              )
                             )
 
              app
                .provide('config', config)
                .use(pinia)
                .use(router)
                .mount('#app') // app is shown to the user
            }

window.addEventListener('load', init)

Dieses muss jedoch händisch implementiert werden.

// src/router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import ViewHome                           from '@/view/ViewHome.vue'

const
  routes =
    [ { path: '/',
        name: 'home',
        component: ViewHome,
      },
      { path: '/hello',
        name: 'hello',
        component: () => import('@/view/ViewHello.vue'),
      },
      { path:      '/:pathMatch(.*)',
        component: () => import('@/view/ViewError404.vue'),
      }
    ],

  router =
    createRouter({ history: createWebHistory(), routes })

export default router

App.vue

Nun kann in die App eine Navigation eingebaut werden.

<!-- /src/App.vue -->

<script setup>
  import AppNav from '@/components/AppNav.vue'
</script>
<template>
  <AppNav/>
  <main>
    <router-view/>
  </main>
</template>

<style lang="scss">
  @import '/css/body';
</style>

Die zugehörige Navigationskomponente muss auch noch implementiert werden.

<!-- /src/components/AppNav.vue -->

<script setup>
</script>
<template>
  <nav>
    <ul>
      <li><router-link to="/">Home</router-link></li>
      <li><router-link to="/hello">Hello</router-link></li>
    </ul>
  </nav>
</template>

<style scoped lang="scss">
  @import '/css/AppNav';
</style>
/* src/css/AppNav.scss */

@import 'config';
nav
{ top:      0;
  width:    100%;
  position: fixed;

  ul
  { list-style-type: none;
    margin: 0 $nav-dist;
    padding: 0;

    li
    { display: inline;
      a { padding: 0 $nav-dist 0.2em; }
    }

    a
    { text-decoration: none;
      color:           $link-color;
      font-weight:     bold;
    }

    a:hover, .router-link-exact-active
    { text-decoration: underline;
      color:           $link-color;
      font-weight:     bold;
    }
  }

  label, input
  { margin: 0;
  }
}

Navigation

Die Navigation muss in allen Komponenten, in den Seiten gewechselt werden, angepasst werden.

Das ist in der App.vue der Fall (siehe zuvor) sowie in der ViewHome.vue.

<!-- /src/App.vue  -->

<script setup>
import FormButton    from '@/component/form/FormButton.vue'
import FromTextfield from '@/component/form/FormTextfield.vue'

import storeGreeting from '@/store/StoreGreeting'
import router        from '@/router'

const
  greeting = storeGreeting(),
  i18n     = greeting.i18n,
  sayHello = () => router.push('/hello')
</script>


Quellen

  1. Kowarschick (WebProg): Wolfgang Kowarschick; Vorlesung „Web-Programmierung“; Hochschule: Hochschule Augsburg; Adresse: Augsburg; Web-Link; 2024; Quellengüte: 3 (Vorlesung)