HTML5-Tutorium: JavaScript: Hello World Vue 04: Unterschied zwischen den Versionen

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 61: Zeile 61:


<style scoped lang="scss">
<style scoped lang="scss">
   @import '/css/form/FormButton';
   @import '/css/components/form/FormButton';
</style>
</style>
</source>
</source>
Zeile 68: Zeile 68:


<source lang="css">
<source lang="css">
// src/css/form/FormButton.scss
// src/css/components/form/FormButton.scss


@import 'Form';
@import 'Form';
Zeile 76: Zeile 76:


<source lang="css">
<source lang="css">
/* src/css/form/_Form.scss */
/* src/css/components/form/_Form.scss */


@import 'config';
@import 'config';
Zeile 135: Zeile 135:


<style scoped lang="scss">
<style scoped lang="scss">
   @import '/css/form/FormTextfield';
   @import '/css/components/form/FormTextfield';
</style>
</style>
</source>
</source>
Zeile 148: Zeile 148:


<source lang="css">
<source lang="css">
/* src/css/form/FormTextfield.scss */
/* src/css/components/form/FormTextfield.scss */


@import 'Form';
@import 'Form';
Zeile 193: Zeile 193:


<style scoped lang="scss">
<style scoped lang="scss">
   @import '/css/section/SectionForm';
   @import '/css/components/section/SectionForm';
</style>
</style>
</source>
</source>


<source lang="scss">
<source lang="scss">
/* src/css/section/SectionForm.scss */
/* src/css/components/section/SectionForm.scss */


@import 'Section';
@import 'Section';
Zeile 204: Zeile 204:


<source lang="scss">
<source lang="scss">
/* src/css/section/_Section.scss */
/* src/css/components/section/_Section.scss */


@import 'config';
@import 'config';
Zeile 242: Zeile 242:


<style scoped lang="scss">
<style scoped lang="scss">
   @import '/css/section/SectionHello';
   @import '/css/components/section/SectionHello';
</style>
</style>
</source>
</source>


<source lang="scss">
<source lang="scss">
/* src/css/section/SectionHello.scss */
/* src/css/components/section/SectionHello.scss */


@import 'Section';
@import 'Section';
Zeile 283: Zeile 283:


<style scoped lang="scss">
<style scoped lang="scss">
   @import '/css/HelloWorld.scss'
   @import '/css/components/HelloWorld.scss'
</style>
</style>
</source>
</source>
Zeile 292: Zeile 292:


<source lang="scss">
<source lang="scss">
/* src/css/HelloWorld.scss */
/* src/css/components/HelloWorld.scss */


@import 'config';
@import 'config';

Version vom 21. April 2024, 10:36 Uhr

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 v04 (JavaScript)
Git-Repository (TypeScript), git checkout v04

Anwendungsfälle (Use Cases)

Gegenüber dem ersten, zweiten und dritten Teil des Vue-Tutoriums ändern sich die die Anwendungsfälle nicht. Die Anwendung leistet also genau dasselbe wie zuvor.

Aufgabe

Aufgabe: Modularisieren Sie HelloWorld.vue Definieren Sie für die Komponente HelloWorld.vue zwei Subkomponenten:

  • components/section/SectionHello.vue
  • components/section/SectionForm.vue

Zuvor sollten Sie zwei wiederverwendbare Hilfskomponenten definieren:

  • components/form/FormButton.vue
  • components/form/FormTextfield.vue

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 v03     # Wechsle in den Branch v03
git checkout -b v04  # Klone v03 in einen neuen Branch v04
npm i
npm i uuid

Erstellen der Hilfskomponenten

FormButton.vue

Eine parametrisierbare Button-Komponente.

<!-- src/components/form/FormButton.vue -->

<script setup>
  defineProps
  ({ type:  { type: String, default: 'button' },
     label: { type: String, default: 'Button' }
  })

  const
    emit  = defineEmits(['click']),
    click = () => emit('click')
</script>

<template>
  <input :value="label" :type="type" @click="click"/>
</template>

<style scoped lang="scss">
  @import '/css/components/form/FormButton';
</style>

Das zugehörige SCSS-Modul importiert lediglich ein SCSS-Modul für Formulare.

// src/css/components/form/FormButton.scss

@import 'Form';

Das Formular-SCSS-Modul definiert Eigenschaften, die sich mehrere Formular-Elemente teilen.

/* src/css/components/form/_Form.scss */

@import 'config';

label
{ font-family: $font-family-serif;
  font-size:   $font-size-p !important;
}

label, input
{ width:      10em;
  font-size:  100%;
  display:    inline-block;
  box-sizing: border-box;
  margin:     0.5ex;
}

label
{ text-align: right; }

FormTextfield.vue

Eine parametrisierbare Textfield-Komponente zum Erfassen von Texteingaben.

// src/components/form/FormTextfield.vue

<script setup>
  import { computed, onMounted, onUnmounted } from 'vue'
  import { v4 as uuid } from 'uuid'
  import ControllerKey  from '@/controller/ControllerKey'

  const
    props         = defineProps
                    ({ label:     { type: String,  default: '' },
                       text:      { type: String,  default: '' },
                       autofocus: { type: Boolean, default: false }
                    }),
    id            = uuid(),
    emit          = defineEmits(['update:text', 'enter']),
    text          = computed
                    ({ get()        { return props.text },
                       set(p_value) { return emit('update:text', p_value) }
                    }),
    enter         = () => emit('enter'),
    controllerKey = new ControllerKey('Enter', enter, id)

  onMounted  (() => controllerKey.add())
  onUnmounted(() => controllerKey.remove())
</script>

<template>
  <div>
    <label :for="id" v-if="label !== ''">{{label}}</label>
    <input :id="id" type="text" v-model="text" :autofocus="autofocus" />
  </div>
</template>

<style scoped lang="scss">
  @import '/css/components/form/FormTextfield';
</style>

Mit Hilfe von "computed" wird für die Property "text" bidirektionales Binding ermöglicht.

Die Getterfunktion liest den Wert aus der Property des Aufrufers. Die Setterfunktion erzeugt bei jeder Änderung ein passendes Ereignis. Der Name des Ereignisse muss laut Vue-Konvention 'update:<Propertyname>' lauten.

Wie zuvor wird das Formular-SCSS-Modul verwendet.

/* src/css/components/form/FormTextfield.scss */

@import 'Form';

Erstellen der Hello-World-Section-Komponenten

SectionForm.vue

SectionForm enthält nur noch ein section-Element. Die Buttons und das Textfield werden als Komponenten eingebunden.

// src/components/section/SectionForm.vue

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

  import storeSection  from '@/store/StoreSection'
  import storeGreeting from '@/store/StoreGreeting'

  const
    section  = storeSection(),
    greeting = storeGreeting(),
    sayHello = () => { section.change('hello') }
</script>

<template>
  <section id="section_form" v-bind:class="section.visability('form')">
    <h1>{{greeting.helloStranger}}</h1>
    <form>
      <div>
        <FormTextfield label="What's your name?" autofocus
                       v-model:text="greeting.name" @enter="sayHello"
        />
      </div>
      <div>
        <FormButton label="Reset" type="reset" />
        <FormButton label="Say Hello" @click="sayHello"/>
      </div>
    </form>
  </section>
</template>

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

@import 'Section';
/* src/css/components/section/_Section.scss */

@import 'config';

section
{ text-align:   center;
  margin-left:  auto;
  margin-right: auto;

  h1
  { font-size:     $font-size-h1;
    margin-bottom: 0.5ex;
  }
}

SectionHello.vue

// src/components/section/SectionHello.vue

<script setup>
  import storeSection  from '@/store/StoreSection'
  import storeGreeting from '@/store/StoreGreeting'

  const
    section  = storeSection(),
    greeting = storeGreeting()
</script>

<template>
  <section id="section_hello" v-bind:class="section.visability('hello')">
    <h1>{{greeting.hello}}</h1>
    <p>Welcome to Web Programming!</p>
  </section>
</template>

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

@import 'Section';

section
{ p
  { font-size: $font-size-p-large !important; }
}

Modularisieren der Hello-World-Komponente

Nun besteht die Hello-World-Komponenten nur noch aus zwei Section-Komponenten.

Allerdings muss noch die Startkomponente, das heißt die Komponenten, die zunächst sichtbar sein soll, initialisiert werden.

Dies kann später entfallen, wenn die Stores mit Hilfe von JSON-Dateien initialisiert werden.

// src/components/HelloWorld.vue

<script setup>
  import SectionForm  from '@/components/section/SectionForm.vue'
  import SectionHello from '@/components/section/SectionHello.vue'

  import storeSection from '@/store/StoreSection'
  const section = storeSection()
  section.init('form')
</script>

<template>
  <SectionForm/>
  <SectionHello/>
</template>

<style scoped lang="scss">
  @import '/css/components/HelloWorld.scss'
</style>

Das Folgende ist nur eine Dummy-SCSS-Datei, die aus Symmetriegründen angelegt wurde: Für jede Komponente gibt es gemäß WK-Konvention eine eigene SCSS-Datei.

/* src/css/components/HelloWorld.scss */

@import 'config';

Bereinigen der Datei body.scss

Die in den obigen SCSS-Modulen enthaltenen Inhalte können und sollten aus der Datei body.scss gelöscht werden.

Fortsetzung des Tutoriums

Sie sollten nun Teil 5 des Vue-Tutoriums bearbeiten. In diesem Tutorium werden die Daten extern aus JSON-Dateien geladen, erst statisch, dann dynamisch. Zum Schluss wird die Anwendung internationalisiert.

Quellen

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