Skip to content
Charles Anjos edited this page Jul 29, 2024 · 10 revisions

CharlesAnjos' Vue3 KB

Introduction

In this repo I plan on annotating on the many observations and examples I hopefully come across in the journey of learning about / working with Vue.js v3.

General usage of this wiki

Most info will be published here in the wiki pages of this project, with code being relayed to other repos within the organization structure.

Basic Functionality Code

Creating and Connecting Vue App Instances

Vue app instances can be created on a javascript file, then connected to an HTML element with a specific ID defined when creating the Vue app instance

  1. On a javascript file
// creates a Vue instance
const app = Vue.createApp({
  data(){ // function that defines data that will be available to the HTML page
    return {
      ...
    };
  },
  methods: {
    ... // methods that will be availabe to use to the HTML page
  }
});

// Connects the Vue instance to an HTML element via an ID
app.mount('#my-vue-app');
  1. On a HTML file:
<html>
  <head>
    ...
    <!-- Vue import via CDN (get an up-to-date version at vuejs.org) -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <!-- Import your script created above -->
    <script src="myscript.js" defer></script>
    ...
  </head>
  <body>
    ...
    <section id="my-vue-app">
      <!-- This element ID defines the element Vue will have control over -->
      <!-- All data and methods defined on the vue app will be available to the HTML elements here -->
    </section>
    ...
  </body>
</html>

Data Interpolation / Binding

Data interpolation is the access of data related to the Vue instance through the connected HTML element. It can be done via the interpolation operator ( {{ }} ) or via data binding directive (v-bind).

  1. In your Vue app script:
const app = Vue.createApp({
  data(){ // function that defines data that will be available to the HTML page
    return {
      var1: 'Hello',
      var2: 123,
      var3: [1,2,3],
      obj1: {params: "you can pass objects"}
      link: 'https://vuejs.org'
    };
  },
  ...
});
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      <!-- Data is accessed from inside elements using the interpolation operator {{ }} -->
      <p>{{ var1 }}</p>
      <p>{{ var2 }}</p>
      <p>{{ var3 }}</p>
      <p>{{ obj1.params }}</p>
      <!-- The following code WILL NOT WORK. Data interpolation can't be used as HTML parameters, only content internal to HTML elements-->
      <p>Learn more <a href="{{link}}">about Vue</a>.</p>
      <!-- For this, it's necessary to use the  v-bind directive and the name of the parameter to be bound to.-->
      <p>Learn more <a v-bind:href="link">about Vue</a>.</p>
    </section>
    ...

Function Calls

Similarly to data, functions can also be created on the Vue instance and accessed by the HTML element bound to it.

  1. In your Vue app script:
const app = Vue.createApp({
  data(){
    ...
  },
  methods: { // Defines methods to be accessed through the HTML element
    oneMethod(){
      ...
      return 'something';
    },
    anotherMethod(){
      ...
      return 'something else';
    },
  }
});
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <!-- Functions can be accessed similarly to data previously shown -->
      <p>{{ oneMethod() }}</p> 
      <p>{{ anotherMethod }}</p>
    </section>
    ...

Access Vue data through Vue functions

Data defined on the Vue instance can only be accessed by functions defined on the Vue instance through the this object, which represents the Vue instance internally

  1. In your Vue app script:
const app = Vue.createApp({
  data(){
    return{
      someVar: 'some value', // Definition of the data
    };
  },
  methods: {
    someMethod(){
      this.someVar = 'some other value' // Access to the data defined before
      return this.someVar;
    }
  }
});

Outputting raw HTML content

It is possible to output content that will be interpreted as HTML directly, viabilizing the dinamic creation of HTML content.

  1. In your Vue app script:
const app = Vue.createApp({
  data(){
    return{
      htmlCode: '<h2>some HTML elements</h2>', // this variable has text that can be interpreted as HTML code
    };
  },
  methods: {
    outputHtml(){
      return this.htmlCode; // Functions can also output HTML code
    }
  }
});
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <!-- The following code WILL NOT WORK. Simple data interpolation will not interpret the HTML code. It will be outputted out as simple text (protection against XSS attacks) -->
      <p>{{ htmlCode }}</p>
      <!-- the v-html directive needs to be used in these cases.  -->
      <p v-html="htmlCode"></p>
      <!-- the v-html directive will also work with functions.  -->
      <p v-html="outputHtml()"></p>
    </section>
    ...

Nevertheless, this SHOULD NOT BE DONE, because you will be intruducing a security flaw by allowing your app to execute HTML code directly, without any checks.

Event binding

Similarly to Data Binding, you can also bind events using the directive v-on, followed by semicolons and the name of the HTML event you want to bind to (click, mouseover, mouseout, etc.)

  1. In your Vue app script:
...
  data() {
    return {
      counter: 0,
    };
  },
  methods: {
    add(){
      this.counter++;
    },
    reduce(){
      this.counter--;
    },
  },
...
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <!-- The v-on directives in the next 2 elements binds clicks to this button to a javascript operation -->
      <button v-on:click="add">Add</button>                         
      <button v-on:click="reduce">Reduce</button>
      <p>Result: {{ counter }}</p>
    </section>
    ...

Passing Arguments though Event Binding

It is possible to pass arguments through Event Binding.

  1. In your Vue app script:
...
  data() {
    return {
      counter: 0,
    };
  },
  methods: {
    add(num){
      this.counter += num;
    },
    reduce(num){
      this.counter -= num;
    },
  },
...
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <!-- Just include the arguments into the funtcion call as any conventional function call -->
      <button v-on:click="add(num)">Add {{ num }}</button>                         
      <button v-on:click="reduce(num*2)">Reduce {{ num*2 }}</button>
      <p>Result: {{ counter }}</p>
    </section>
    ...

Managing events via the native Event Object

For more advanced event handling, it is possible to handle the events using the Event Object which is native to JavaScript. This allows for more complex behavior, i.e. receiving data from the elements, like field values in an input element.

  1. In your Vue app script:
  data() {
    return {
      name: '',
    };
  },
  methods: {
    setName(event){ // event will be the Event Object sent by the page
      this.name = event.target.value
       // inside of the Event Object you have access to the Object parameters of the elements involved. target is the element which was the target of the event (in our case, the input element, from which the event is started) and inside of target element, the value parameter (which holds the content typed by the user on the field)
    }
  },
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <!-- The event object is automatically included in the function call if there's no () on it. Putting () on the function call overwrites the list of parameters and removes the event object that would be sent by default. In this case, it is possible to include the parameter $event in the function call -->
      <input v-on:input="setName" type="text">
      <p>Your Name: {{ name }}</p>
    </section>
    ...

Events and Modifiers

Sometimes HTML events have results that are undesirable, i.e. automatic reload after clicking a button on a form. In such cases, it is necessary to modify the event to alter it's execution from the default. This can be achieved with the native Javascript method preventDefault() which is present in the default Event Object, but Vue also has a solution for this: you can call event modifiers in the v-on directive call by adding a dot after the name of the event.

  1. In your Vue app script:
  data() {
    return {
      name: '',
    };
  },
  methods: {
    setName(event){
      this.name = event.target.value;
    },
    confirmName(event){
      this.confirmedName = this.name;
    },
    submitForm(event){
      event.preventDefault(); // native JavaScript method to modify the default process of an event.    Not necessary if you call the modifier from the Vue directive.
      alert('Submitted!');
    },
  },
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <input v-on:keyup.enter="confirmName" type="text"> <!-- Different HTML events have different event modifiers supported by Vue. Consult the docs for a complete list. -->
      <p>Your Name: {{ confirmedName }}</p>
      <form v-on:submit.prevent="submitForm"> <!-- Vue call of the prevent modifier -->
        <input type="text">
        <button>Sign Up</button>
      </form>
    </section>
    ...

Locking content from updating

It might be desirable to stop some value from updating beyond the initial value. For that, the v-once directive can be used.

  1. In your Vue app script:
  data() {
    return {
      counter: 0,
      num: 5,
    };
  },
  methods: {
    add(num){
      this.counter 
  },
  1. In your HTML file:
    ...
    <section id="my-vue-app">
      ...
      <button v-on:click="add(num)">Add {{ num }}</button>                         
      <button v-on:click="reduce(num*2)">Reduce {{ num*2 }}</button>
      <p v-once>Result: {{ counter }}</p> <!-- This counter will not update beyond the initial value-->
      <p>Result: {{ counter }}</p>
    </section>
    ...

Data Binding + Input Binding = Two Way Binding

Very common are the cases where it is necessary to bind data to an input element and at the same time bind the value of this input to some data on your Vue app. In this case, you would declare your bindings like this:

  <!-- this works, but it is long and annoying -->
  <input type="text" v-bind:value="name" v-on:input="setName" />

with v-bind binding the data and v-on binding the input. So common this case is, Vue implemented a two-way binding, so you don't need to use both directives, just a shorter one. So instead of the code demonstrated above, you do this:

  <!-- this also works, AND it is shorter and better -->
  <input type="text" v-model="name"/>

This has the exact same effect as the other code above it: it binds to the data (variable name) and to the input (function setName). Quite handy.

Repos with basic implementations

Clone this wiki locally