Testen, probieren für Vue, JS, Node, Typscript und vieles mehr
Kategorie: Vue
Eigene Directive (focus), die nach dem die App fertig gemountet wurde den focus auf Elemente setzt.
# /directive/focus.js
export default {
mounted(el){
el.focus();
}
}
Globale Einbindung der Directive
import { createApp } from 'vue'
import App from './App.vue'
import logger from './mixins/logger';
import focus from './directive/focus';
const app = createApp(App);
app.mixin(logger)
app.directive('focus',focus)
app.mount('#app')
Verwendung der Directive
Bezeichner v- voranstellen
<input
type="text"
class="form-control"
placeholder="Neue Aufgabe"
v-model="content"
v-focus
/>
Wir können somit Daten über mehreren Komponenten direkt einbinden.
Nachteil:
* das Kindelement weiss nicht woher diese Daten kommen
* die inject-Daten sind nicht reaktiv
* provide / inject nur nutzen, wenn mit statischen Daten gearbeitet wird, die sich nicht reactiv aktualisieren
* Nutzung eines stores erübrigt das Problem
#Elternkomponente, Bereitstellung der Daten
export default {
name: "App",
components: {
StatusCard,
},
provide:(){
maxNumbersOfChars: 255,
},
#Enkel(Kind)komponente, Daten-Injection
export default {
name: "NewTask",
inject: ["maxNumbersOfChars"],
computed: {
numberOfCharsLeft() {
return this.maxNumbersOfChars - this.content.length;
},
},
Daten von Kind an Elternkomponente ( Emit)
Wenn Daten als Props von der Root-Komponente an die unteren Kind-Komponenten übergeben werden und die Datenhaltung in der Elternkomponente stattfindet, können die Daten bspw. über eigene Ereignishandler hochgereicht werden, um diese hinzuzufügen.
Bspw.
Elternkomponente -> Kind -> Enkelkind
APP.vue -> StatusCard.vue -> NewTask.vue
Um Daten von NewTask an APP.vue ( Datenhaltung) zu übertragen, nutzen wir:
this.$emit('custom-ereignis',payload);
In der höheren Komponente können wir das Ereignis dann abfangen.
<NewTask v-if="newTasks" @custom-ereignis="createNewTask"></NewTask>
#NewTask.vue
<button class="btn btn-secondary" @click="submitTask">Eintragen</button>
export default {
emits: {
"new-task": (task) => {
if (task.content === "") {
console.warn("Der Content sollte nich leer sein");
return false;
}
return true;
},
},
data() {
return {
content: "",
};
},
methods: {
submitTask() {
this.$emit("new-task", {
//Payload
content: this.content,
});
this.content = "";
},
},
}
#StatusCard.vue
<NewTask v-if="newTasks" @new-task="createNewTask"></NewTask>
emits: {
"new-task": (task) => {
if ("status" in task === false) {
console.warn(
"StatusCardComponent: Jede Aufgabe muss ein Status-Attribut haben."
);
export default {
name: "StatusCard",
components: {
Task: OneTask,
NewTask,
},
emits: {
"new-task": (task) => {
if ("status" in task === false) {
console.warn(
"StatusCardComponent: Jede Aufgabe muss ein Status-Attribut haben."
);
return false;
}
return true;
},
},
props: {
// card: {
// type: Object,
// },
title: String,
titleClasses: String,
status: Number,
newTasks: Boolean,
tasks: {
type: Array,
},
},
computed: {
},
methods: {
createNewTask(task) {
console.log(task);
// Nicht möglich, da task als PROP übergeben wurde und Urheber der Daten ist App.vue
// this.tasks.push(task);
task.status = this.status;
this.$emit("new-task",task);
},
},
};
</script>
- besitzt das mixin gleiche Attribute oder Methoden, wie auch die Komponente, werden diese zusammengeführt
- bei gleichen Methodennamen in Mixin und Komponente hat die der Komponente Vorrang und die mixin-Methode verfällt
Methodenname daher entsprechend anpassen - Life-Cycle Hooks (mounted) haben in den Mixins Vorrang, dann erst die Hooks aus der Komponente
LOKALE EINBINDUNG
# /mixin/logger.js - mounted und methods
export default {
mounted(){
this.writeLogEntry(`${this.$options.name}-Component vollständig geladen`);
},
methods: {
writeLogEntry(text){
console.log(text);
}
}
}
#App.vue - verwendet mixin und hat eigene method und mounted
export default {
name: "App",
mixins: [logger],
components: {
StatusCard,
},
mounted(){
console.log("APP Komponente vollständig geladen");
},
GLOABALE EINBINDUNG
#main.js
import { createApp } from 'vue'
import App from './App.vue'
import logger from './mixins/logger';
const app = createApp(App);
app.mixin(logger)
app.mount('#app')
Daten von außen nach innen reichen. Slots sind Platzhalter, die von außen gefüllt werden. So kann bspw. vorgegeben werden welche Angaben erwartet werden.
#default
<slot></slot>
<slot name="title"></slot>
Von außen angesteuert:
<template v-slot:title>Text der durchgereicht wird</template>
Kurzschreibweise
<template #title>Titeltext</template>
Freigabe von Daten von innen nach aussen
Definition Slot-Name
<slot name="eventdaten" :eventNameVonAussen="eventDaten"></slot>
Ansteuerung Slot mit Namen
<template #eventdaten="slotProps">{{ slotProps.eventDaten }}</template>
Die Daten werden nach aussen gereicht, Vue sammelt alle Daten, Funktion, Objekte. Wir bestimmen "slotProps" in dem alles gesammelt wurde. Name frei wählbar.