Vue - Snippets: Unterschied zwischen den Versionen

Aus Wikizone
Wechseln zu: Navigation, Suche
 
(118 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
== Basics ==
+
== Links ==
* Data Option / Function
+
[[Vue.js]]
* Methods Option / Object
+
[[Vue - Basic Concepts]]
* Outputting Data mit
+
[[Vue CLI]]
** Interpolation {{}}
+
[[Vue - Components]]
** Bindings v-bind:property="myVal"
 
** Methods
 
** JavaScript Objects
 
* this
 
  
 +
== Snippets ==
 +
=== Starters ===
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
// create App
 
const app = Vue.createApp();
 
// mount a html region
 
// app.mount('cssSelector');
 
app.mount('#myId'); // Vue controls now this id in the DOM
 
 
 
 
const app = Vue.createApp({
 
const app = Vue.createApp({
  // DATA FUNCTION can hold key val pairs
+
   data(){
   data() { //or data: function(){...}
+
     return{
     return{ // data always returns an object
 
      myVar: 'Learn Vue',// can store keys with vals of every type(bool, object, string...)
 
      myVar2: 'Master Vue<,
 
      myHTML: '<h3>HTML Code</h3>', // use v-html to output html code
 
      myLink: 'https://viewjs.org'
 
    };
 
  }
 
  // METHODS OBJECT HOLDS FUNCTIONS
 
  methods: {
 
    outputGoal(){
 
      const randomNumber = Math.random();
 
      if (randomNumber < 0.5) {return 'Learn Vue';}
 
      else {return this.myVar2} // 'this' works because vue merges all data and methods in a global vue object
 
 
     }
 
     }
 +
  },
 +
  methods:{
 +
  },
 +
  computed:{
 +
  },
 +
  watch:{
 
   }
 
   }
 
});
 
});
 +
app.mount('#assignment');
 +
</syntaxhighlight>
 +
 +
==== Starter mit main.js (CLI) ====
 +
<syntaxhighlight lang="javascript">
 +
import { createApp } from 'vue';
 +
// Import Main App
 +
import App from './App.vue';
 +
// Import Global Components
 +
import BaseBadge from './components/BaseBadge.vue';
 +
import BaseCard from './components/BaseCard.vue'
 +
// Create App Instance
 +
const app = createApp(App);
 +
// Register Components
 +
app.component('base-badge', BaseBadge);
 +
app.component('base-card', BaseCard)
 +
// Mount App
 +
app.mount('#app');
 +
 +
</syntaxhighlight>
 +
 +
=== Using this in a submethod i.e. Timer ===
 +
<syntaxhighlight lang="javascript">
 +
watch:{
 +
  // it is allowed to watch computed properties
 +
  result(value){
 +
    const that = this;
 +
    setTimeout(function(){
 +
      console.log("timeout");
 +
      that.counter = 0;
 +
      return 0;
 +
    },3000);
 +
  }
 +
}
 +
</syntaxhighlight>
 +
 +
=== Toggle Classes ===
 +
<syntaxhighlight lang="javascript">
 +
//...
 +
data(){ return { boxSelected: false } },
 +
methods:{ toggleBox(){ this.boxSelected = !this.boxSelected; } }
 +
//...
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
<syntaxhighlight lang="html5">
 
<syntaxhighlight lang="html5">
<div id="myId">
+
<div @click="selectBox()" class="box" :class="{ active : boxSelected }"></div>
<h3>Interpolation</h3>
 
<p>{{ myVar }}</p> <!-- Interpolation outputs "Learn Vue" -->
 
<h3>Binding</h3>
 
<p>Use bindings to set attributes. I.e. set the href attribute. {{myLink}} wouldn't work inside of tags.</p>
 
<p>Learn more <a v-bind:href="myLink">about Vue</a></p>
 
<p>{{ outputGoal() }}</p><!-- functions or simple js expresseions like 1+1 work to -->
 
<p v-html="myHTML"></p>
 
</div>
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Events ==
+
=== Add and remove items to / from a list ===
=== v-on ===
 
=== Beispiel ===
 
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
 
const app = Vue.createApp({
 
const app = Vue.createApp({
 
   data() {
 
   data() {
     return {
+
     return {  
       counter: 0,
+
       enteredGoalValue: '',
    };
+
      goals: []
 +
    };
 
   },
 
   },
   methods:{
+
   methods: {
     plus(n){ this.counter = this.counter + n },
+
     addGoal() {
    minus(n){ this.counter = this.counter - n },
+
      this.goals.push(this.enteredGoalValue);
     updateName(event){
+
      this.enteredGoalValue = '';
       this.name = event.target.value
+
    },
 +
     removeGoal(i){
 +
      console.log("removeGoal " + i)
 +
       this.goals.splice(i,1); // splice 1 item at index i
 
     }
 
     }
 
   }
 
   }
 
});
 
});
 +
app.mount('#user-goals');
 +
</syntaxhighlight>
  
app.mount('#events');
+
<syntaxhighlight lang="html5">
 +
  <section id="user-goals">
 +
      <h2>My course goals</h2>
 +
      <input type="text" v-model="enteredGoalValue" />
 +
      <button @click="addGoal">Add Goal</button>
 +
      <p v-if="goals.length === 0">No goals have been added yet - please start adding some!</p>
 +
      <ul v-else>
 +
        <li v-for="(goal, i) in goals" @click="removeGoal(i)" :key="[myID]">#{{i}} {{goal}}</li> // use a unique id for key attribute
 +
      </ul>
 +
    </section>
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
=== Components ===
 +
==== Component Todos ====
 +
'''Mit CLI'''
 +
* myComponent.vue Datei erstellen
 +
* In main.js Import und component Funktion
 +
* In App.vue Import
 +
* In myComponent.vue props, emits festlegen
 +
* In App.vue emits als v-on nutzen
 +
* In App.vue props als Argumente übergeben
 +
==== Basic Component ====
 +
Parent
 
<syntaxhighlight lang="html5">
 
<syntaxhighlight lang="html5">
<section id="events">
+
<template>
  <h2>Events in Action</h2>
+
    <h1>My App</h1>
  <p> We can use expression in v-on:click or use a function from our methods object</p>
+
    <ul>
  <!-- CLICK EVENT -->
+
        <learning-resource v-for="res in storedResources"
  <button v-on:click="plus(5)">Add 5</button>
+
            :key="res.id"
  <button v-on:click="minus(5)">Substract 5</button>
+
            :title="res.title"
  <p>Result: {{ counter }}</p>
+
            :description="res.description"
  <!-- INPUT EVENT -->
+
            :link="res.link">
   <input type="text" v-on:input="updateName">
+
        </learning-resource>
  <p>Hello {{ name }}</p>
+
    </ul>
 +
</template>
 +
<script>
 +
import LearningResource from './components/learning-resources/LearningResource.vue'
 +
 
 +
export default {
 +
    components:{
 +
        LearningResource,
 +
    },
 +
    data(){
 +
        return {
 +
            storedResources: [
 +
                {    
 +
                    id: 'official-guide',
 +
                    title: 'Official Guide',
 +
                    description: 'The official Vue.js documentation',
 +
                    link: 'https://vuejs.org'
 +
                },
 +
                {
 +
                    id: 'google',
 +
                    title: 'Google',
 +
                    description: 'Search for other things...',
 +
                    link: 'https://google.de'
 +
                },
 +
            ]
 +
        }
 +
    }
 +
}
 +
</script>
 +
</syntaxhighlight>
  
</section>
+
Child
 +
<syntaxhighlight lang="html5">
 +
<template>
 +
<li>
 +
  <h3> {{ title }} </h3>
 +
  <p>  {{ description }}  </p>
 +
  <nav>
 +
    <a :href="link">View resource</a>
 +
  </nav>
 +
</li>
 +
</template>
 +
<script>
 +
export default {
 +
    props: ['title', 'description', 'link']
 +
}
 +
</script>
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== $event ===
+
=== Slots ===
In Eventlistenern kann man automatisch auf das event Argument zugreifen, das der Browser automatisch mitliefert (siehe Beispiel oben). Wenn man allerdings selbst ein Argument übermittelt wird das Event Argument überschrieben. Man kann aber mit dem reservierten Argument $event trotzdem wieder auf das Event Objekt zugreifen:
+
Basic Slot
  
 +
'''App.vue'''
 +
<syntaxhighlight lang="html5">
 +
</syntaxhighlight>
 +
 +
=== Send Receive REST Data ===
 +
Das folgende Beispiel bezieht und sendet JSON Daten von / zu einer Firebase Datenbank. Das Prinzip läßt sich auf alle REST Schnittstellen adaptieren.
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
    updateName(event, lastName){
+
loadExperiences() {
       this.name = event.target.value + ' ' + lastName
+
       this.isLoading = true;
 +
      this.error = null;
 +
      fetch('https://vue-course-http-01-default-rtdb.firebaseio.com/surveys.json')
 +
        .then( (response) => {
 +
          // is executed when data arrived. Arg response is provided automatically.
 +
          if (response.ok) {
 +
            return response.json(); // parse json data and return promise
 +
          }
 +
        })
 +
        .then( (data) => {
 +
          // executed when promise returned
 +
          // hint if we would use function(data) instead of arrow function
 +
          // the keyword this would not work
 +
          this.isLoading = false;
 +
          console.log('Received Data: ');
 +
          console.log(data);
 +
          const results = [];
 +
          for( const id in data){
 +
            results.push({ id: id, name: data[id].name, rating: data[id].rating})
 +
          }
 +
          this.results = results;
 +
        })
 +
        .catch(
 +
          // catch will be triggered when an error in any of the previous promises occurs
 +
          // argument error is provided automatically in the function
 +
          (error) => {
 +
            console.log('Error' + error);
 +
            this.isLoading = false;
 +
            this.error = 'Failed to fetch data: ' + error;
 +
          }
 +
        );
 
     }
 
     }
 
</syntaxhighlight>
 
</syntaxhighlight>
<syntaxhighlight lang="html5">
+
 
       <input type="text" v-on:input="updateName($event,'Schlegel')">
+
<syntaxhighlight lang="javascript">
       <p>Hello {{ name }}</p>
+
submitSurvey() {
 +
       if (this.enteredName === '' || !this.chosenRating) {
 +
        this.invalidInput = true;
 +
        return;
 +
      }
 +
      this.invalidInput = false;
 +
 
 +
      // this.$emit('survey-submit', {
 +
      //  userName: this.enteredName,
 +
      //  rating: this.chosenRating,
 +
      // });
 +
      this.error = null;
 +
      fetch('https://vue-course-http-01-default-rtdb.firebaseio.com/surveys.json', {
 +
        method: 'POST',
 +
        headers: {
 +
          'Content-Type': 'application/json'
 +
        },
 +
        body: JSON.stringify({
 +
          name: this.enteredName,
 +
          rating: this.chosenRating
 +
        }),
 +
      })
 +
       .then( response => {
 +
        if (response.ok) {
 +
          console.log("We got a valid response from server: " + response);
 +
        }else{
 +
          throw new Error('Could not save data');
 +
          // this creates new Error Object which we receive in catch()
 +
        }
 +
      })
 +
      .catch(error => {
 +
        console.log(error);
 +
        this.error = error.message;
 +
      });
 +
 
 +
      this.enteredName = '';
 +
      this.chosenRating = null;
 +
    }
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Event Modifiers ===
+
=== Utilities / nützliche Funktionen ===
Es gibt verschiedene Event Modifier z.B. um sich ein event.preventDefault() zu sparen. Event Modifiers werden mit einem '.' an das Event im HTML angehängt
+
Normale JavaScript Funktionen die oft nützlich im Zusammenhang mit Vue sind.
v-on:submit.prevent
+
 
 +
Siehe [[JavaScript - Snippets]]
 +
 
 +
==== Arrays ====
 +
===== Elemente hinzufügen / entfernen =====
 +
Gegeben ist ein Array items in der Art
 +
[{id: 1, name: Anton, isFavourite: true}, {id: 2, name: Berta},...]
 +
<syntaxhighlight lang="javascript">
 +
 
 +
// add to end of array
 +
this.friends.push(newFriend)
  
https://vuejs.org/v2/guide/events.html#Event-Modifiers
+
// add to start of array
==== Click Modifiers ====
+
this.friends.unshift(newFriend)
v-on:click.right
 
v-on:click.middle
 
...
 
  
==== Key Modifiers ====
+
// delete item from array via id (will not work with provide/inject data in components)
//.enter means fire only if ENTER Key is pressed
+
deleteItem(id){
v-on:keyup.enter="confirmInput" //possible is all ctrl, shift, page-down...
+
  this.items = this.items.filter( item => item.id !== sarchId)
 +
  // filter( filterFunction ) uses filterFunction for every item in items.
 +
  // If filterFunction returns true the item is kept. item.id !== id returns true for every
 +
  // item which has NOT the id
 +
}
 +
// this works because we change the array directly
 +
deleteItem(id){
 +
  const itemIndex = this.items.findIndex(item => item.id === id)
 +
  this.items.splice(resIndex, 1);
 +
}
 +
</syntaxhighlight>
  
<syntaxhighlight lang="html5">
+
===== Finden und Suchen =====
<!--also multiple v-on handlers are possible-->
+
<syntaxhighlight lang="javascript">
<input type="text" v-on:input="updateName($event,'Schlegel')" v-on:keyup.enter="confirmName">
+
// find in array and change prop
<p>Hello {{ confirmedName }}</p>
+
const identifiedItem = this.items.find(
 +
  (item) => item.id === searchId // the same as function(friend){return friend.id...}
 +
)
 +
// filter(callback) - callback is executed on every array (array item) first item match is returned
 +
identifiedItem.isFavourite = !identifiedItem.isFavourite
 +
// identifiedItem is a proxy connected to the original items array.
 +
// thus why we can modify identifiedItems and items will be altered too
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
===== Validierung =====
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
const app = Vue.createApp({
+
submitData(){
   data() {
+
  const enteredTitle = this.$refs.titleInput.value;
     return {
+
   if (enteredTitle.trim() === ''){
      name: '',
+
    this.inputIsValid = false;
      confirmedName: '',
+
     return;
    };
+
}
  },
+
</syntaxhighlight>
  methods:{
+
 
    updateName(event, lastName){
+
===== Sonstiges =====
      this.name = event.target.value + ' ' + lastName
+
''Underscore Argumente'' - nutze diese wenn du Argumente, die automatisch bereitgestellt werden nicht benötigst. Dann meckert der Compiler nicht:
    },
+
scrollBehavior(to, from, savedPosition){// compiler tells you that you don't use them}
    confirmName(){
+
scrollBehavior(_, _2, savedPosition){
      this.confirmedName = this.name
+
  console.log(savedPosition) // compiler does not complain :-)
    }
 
 
   }
 
   }
});
 
app.mount('#events');
 
</syntaxhighlight>
 

Aktuelle Version vom 9. Januar 2021, 02:00 Uhr

Links[Bearbeiten]

Vue.js
Vue - Basic Concepts
Vue CLI
Vue - Components

Snippets[Bearbeiten]

Starters[Bearbeiten]

const app = Vue.createApp({
  data(){
    return{
    }
  },
  methods:{
  },
  computed:{
  },
  watch:{
  }
});
app.mount('#assignment');

Starter mit main.js (CLI)[Bearbeiten]

import { createApp } from 'vue';
// Import Main App
import App from './App.vue';
// Import Global Components
import BaseBadge from './components/BaseBadge.vue';
import BaseCard from './components/BaseCard.vue'
// Create App Instance
const app = createApp(App);
// Register Components
app.component('base-badge', BaseBadge);
app.component('base-card', BaseCard)
// Mount App
app.mount('#app');

Using this in a submethod i.e. Timer[Bearbeiten]

watch:{
  // it is allowed to watch computed properties
  result(value){
    const that = this;
    setTimeout(function(){
      console.log("timeout");
      that.counter = 0;
      return 0;
    },3000); 
  }
}

Toggle Classes[Bearbeiten]

//...
data(){ return { boxSelected: false } },
methods:{ toggleBox(){ this.boxSelected = !this.boxSelected; } }
//...
<div @click="selectBox()" class="box" :class="{ active : boxSelected }"></div>

Add and remove items to / from a list[Bearbeiten]

const app = Vue.createApp({
  data() {
    return { 
      enteredGoalValue: '',
      goals: []
     };
  },
  methods: {
    addGoal() {
      this.goals.push(this.enteredGoalValue);
      this.enteredGoalValue = '';
    },
    removeGoal(i){
      console.log("removeGoal " + i)
      this.goals.splice(i,1); // splice 1 item at index i 
    }
  }
});
app.mount('#user-goals');
   <section id="user-goals">
      <h2>My course goals</h2>
      <input type="text" v-model="enteredGoalValue" />
      <button @click="addGoal">Add Goal</button>
      <p v-if="goals.length === 0">No goals have been added yet - please start adding some!</p>
      <ul v-else> 
        <li v-for="(goal, i) in goals" @click="removeGoal(i)" :key="[myID]">#{{i}} {{goal}}</li> // use a unique id for key attribute
      </ul>
    </section>

Components[Bearbeiten]

Component Todos[Bearbeiten]

Mit CLI

  • myComponent.vue Datei erstellen
  • In main.js Import und component Funktion
  • In App.vue Import
  • In myComponent.vue props, emits festlegen
  • In App.vue emits als v-on nutzen
  • In App.vue props als Argumente übergeben

Basic Component[Bearbeiten]

Parent

<template>
    <h1>My App</h1>
    <ul>
        <learning-resource v-for="res in storedResources" 
            :key="res.id"
            :title="res.title"
            :description="res.description"
            :link="res.link">
        </learning-resource>
    </ul>
</template>
<script> 
import LearningResource from './components/learning-resources/LearningResource.vue'

export default {
    components:{
        LearningResource,
    },
    data(){
        return {
            storedResources: [
                {   
                    id: 'official-guide',
                    title: 'Official Guide',
                    description: 'The official Vue.js documentation',
                    link: 'https://vuejs.org'
                },
                {
                    id: 'google',
                    title: 'Google',
                    description: 'Search for other things...',
                    link: 'https://google.de'
                },
            ]
        }
    }
}
</script>

Child

<template>
<li>
  <h3> {{ title }} </h3>
  <p>  {{ description }}  </p>
  <nav>
    <a :href="link">View resource</a>
  </nav>
</li>
</template>
<script>
export default {
    props: ['title', 'description', 'link']
}
</script>

Slots[Bearbeiten]

Basic Slot

App.vue

Send Receive REST Data[Bearbeiten]

Das folgende Beispiel bezieht und sendet JSON Daten von / zu einer Firebase Datenbank. Das Prinzip läßt sich auf alle REST Schnittstellen adaptieren.

loadExperiences() {
      this.isLoading = true;
      this.error = null;
      fetch('https://vue-course-http-01-default-rtdb.firebaseio.com/surveys.json')
        .then( (response) => { 
          // is executed when data arrived. Arg response is provided automatically.
          if (response.ok) {
            return response.json(); // parse json data and return promise
          }
        })
        .then( (data) => {
          // executed when promise returned
          // hint if we would use function(data) instead of arrow function 
          // the keyword this would not work
          this.isLoading = false;
          console.log('Received Data: ');
          console.log(data);
          const results = [];
          for( const id in data){
            results.push({ id: id, name: data[id].name, rating: data[id].rating})
          }
          this.results = results;
        })
        .catch(
          // catch will be triggered when an error in any of the previous promises occurs
          // argument error is provided automatically in the function
          (error) => {
            console.log('Error' + error);
            this.isLoading = false;
            this.error = 'Failed to fetch data: '  + error;
          }
        );
    }
submitSurvey() {
      if (this.enteredName === '' || !this.chosenRating) {
        this.invalidInput = true;
        return;
      }
      this.invalidInput = false;

      // this.$emit('survey-submit', {
      //   userName: this.enteredName,
      //   rating: this.chosenRating,
      // });
      this.error = null;
      fetch('https://vue-course-http-01-default-rtdb.firebaseio.com/surveys.json', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          name: this.enteredName,
          rating: this.chosenRating
        }),
      })
      .then( response => {
        if (response.ok) {
          console.log("We got a valid response from server: " + response);
        }else{
          throw new Error('Could not save data'); 
          // this creates new Error Object which we receive in catch()
        }
      })
      .catch(error => {
        console.log(error);
        this.error = error.message;
      });

      this.enteredName = '';
      this.chosenRating = null;
    }

Utilities / nützliche Funktionen[Bearbeiten]

Normale JavaScript Funktionen die oft nützlich im Zusammenhang mit Vue sind.

Siehe JavaScript - Snippets

Arrays[Bearbeiten]

Elemente hinzufügen / entfernen[Bearbeiten]

Gegeben ist ein Array items in der Art

[{id: 1, name: Anton, isFavourite: true}, {id: 2, name: Berta},...]
// add to end of array
this.friends.push(newFriend)

// add to start of array
this.friends.unshift(newFriend)

// delete item from array via id (will not work with provide/inject data in components)
deleteItem(id){
  this.items = this.items.filter( item => item.id !== sarchId)
  // filter( filterFunction ) uses filterFunction for every item in items.
  // If filterFunction returns true the item is kept. item.id !== id returns true for every
  // item which has NOT the id
}
// this works because we change the array directly
deleteItem(id){
  const itemIndex = this.items.findIndex(item => item.id === id)
  this.items.splice(resIndex, 1);
}
Finden und Suchen[Bearbeiten]
// find in array and change prop
const identifiedItem = this.items.find(
  (item) => item.id === searchId // the same as function(friend){return friend.id...}
)
// filter(callback) - callback is executed on every array (array item) first item match is returned
identifiedItem.isFavourite = !identifiedItem.isFavourite
// identifiedItem is a proxy connected to the original items array.
// thus why we can modify identifiedItems and items will be altered too
Validierung[Bearbeiten]
submitData(){
  const enteredTitle = this.$refs.titleInput.value;
  if (enteredTitle.trim() === ''){
    this.inputIsValid = false;
    return;
}
Sonstiges[Bearbeiten]

Underscore Argumente - nutze diese wenn du Argumente, die automatisch bereitgestellt werden nicht benötigst. Dann meckert der Compiler nicht:

scrollBehavior(to, from, savedPosition){// compiler tells you that you don't use them}
scrollBehavior(_, _2, savedPosition){
  console.log(savedPosition) // compiler does not complain :-)
 }