DEV Community

Amine
Amine

Posted on

First post: Vue learning plan

Vue as most of us know, has gone through a lot of changes mainly introduced through the composition API, in this article, I started a guide to help new Vue lovers or those trying to move from other frameworks to VueJs. I will make more articles to cover more related concepts.

  • Template syntax: Basically here you will learn about the <template> <template/> part found in any in any SFC (Single File Component)
  • Reactivity : Here you will learn about how you interact with data (creation, accessibility,...). also you will learn about ref() and reactive() which will help you deal with that, you will learn the difference between both of them and you'll get to decide when to use each one.

The reason why ref is used for single values, while reactive is used for objects or nested data structures, lies in the way Vue 3's reactivity system works under the hood.

ref for single values:
The ref function is designed to handle the reactivity of single, primitive values like strings, numbers, and booleans. These values are known as "plain old data" or "immutable data" because they cannot be modified directly; instead, they need to be reassigned to a new value.

When you create a reactive reference using ref(value), Vue internally wraps the value in an object and creates a getter and setter for the .value property. This allows Vue to track changes to the value and trigger updates whenever the .value property is reassigned.

Here's a simplified example of how ref works internally:

function ref(value) {
  const wrapper = {
    value,
    get value() {
      // Track dependency
      return value
    },
    set value(newValue) {
      // Trigger updates
      value = newValue
    }
  }
  return wrapper
}
Enter fullscreen mode Exit fullscreen mode

By using .value to access and update the value, Vue can properly track dependencies and trigger updates when necessary.

reactive for objects and nested data structures:
On the other hand, the reactive function is designed to handle the reactivity of objects and nested data structures, such as arrays, objects, and more complex data types. These data structures are known as "mutable data" because their properties or elements can be directly modified.

When you create a reactive object using reactive(obj), Vue internally "proxies" the object, which means it creates a special proxy object that wraps the original object. This proxy object intercepts property access and mutations on the original object, allowing Vue to track dependencies and trigger updates accordingly.

Here's a simplified example of how reactive works internally:

function reactive(obj) {
  const proxy = new Proxy(obj, {
    get(target, key) {
      // Track dependency
      return target[key]
    },
    set(target, key, value) {
      // Trigger updates
      target[key] = value
      return true
    }
  })
  return proxy
}
Enter fullscreen mode Exit fullscreen mode

By using the proxy object, Vue can intercept property access and mutations, track dependencies, and trigger updates when necessary.

The reason reactive is preferred for objects and nested data structures is that it provides a more efficient and straightforward way to handle reactivity for these complex data types. With ref, you would need to create multiple reactive references for each property or element, which can become cumbersome and less efficient for larger data structures.

Additionally, using reactive for objects and nested data structures better aligns with the way developers typically work with these data types in JavaScript, making the code more intuitive and easier to reason about.

In summary, ref is used for single, primitive values because it provides a simple way to create reactive references and track changes to these immutable data types. reactive, on the other hand, is used for objects and nested data structures because it leverages the power of proxies to efficiently handle reactivity for mutable data types, while preserving the natural way of working with objects and arrays in JavaScript.

  • Computed properties : They are basically 'automatically calculated variables', they can be used in both template and script parts in vue components. Generally we use them to get a value or an object that changes based other value(s). ex:
<script setup>
import { reactive, computed } from 'vue'

const input = ref({
    weight: 82,
    height: 1,70
})

// a computed ref
const bmi = computed(() => { return input.weight/(Math.sqrt(input.height)) })
</script>

<template>
  <span>Your BMI is: {{ bmi }}</span>
</template>
Enter fullscreen mode Exit fullscreen mode
  • Class/Style binding : Here you will mainly learn about how you can interact with your css using data binding to make it adapt to any situation you come across. Ex: conditionally apply a dark mode styling depending on the value returned from a dark mode toggle
  • Directives Also knows as life saviors hhhhh, they are special HTML attributes with the prefix v- that give the HTML tag extra functionality. Better check the difference between v-if and v-show to learn more about conditional rendering. also check List rendering using v-for
  • Event Handling : In Vue.js, event handling allows you to respond to user interactions, such as clicks, input changes, and other DOM events. Here's a summary of event handling in Vue.js:

    1. Handling DOM Events:

    • v-on Directive:
      • The v-on directive is used to attach event listeners to DOM elements.
      • It can be used in various ways, such as v-on:click, v-on:input, etc.
    • Shorthand for v-on:
      • Vue provides a shorthand for v-on using the @ symbol. For example, @click is equivalent to v-on:click.

2. Methods for Event Handling:

  • Event Handling Methods:

    • You can define methods in your Vue instance or component and call them when an event occurs.
    • Example:

      <button v-on:click="handleClick">Click me</button>
      
    ```
    new Vue({
      methods: {
        handleClick() {
          console.log('Button clicked!');
        }
      }
    });
    ```
Enter fullscreen mode Exit fullscreen mode
  • Passing Parameters:

    • You can pass additional parameters to your methods using the v-on directive.
    • Example:

      <button v-on:click="handleClick('Hello')">Click me</button>
      
    ```
    new Vue({
      methods: {
        handleClick(message) {
          console.log('Button clicked with message:', message);
        }
      }
    });
    ```
Enter fullscreen mode Exit fullscreen mode

3. Event Modifiers:

  • Preventing Default:

    • Use the .prevent modifier to prevent the default behavior of an event.
    • Example:

      <form v-on:submit.prevent="handleSubmit">Submit</form>
      
  • Stop Propagation:

    • Use the .stop modifier to stop the event propagation.
    • Example:

      <div v-on:click.stop="handleClick">Click me</div>
      
  • Key Modifiers:

    • You can use key modifiers to respond to specific keys. For example, @keydown.enter.

4. Inline Statements:

  • Inline Event Handling:

    • You can also handle events directly in the template using inline statements.
    • Example:

      <button @click="() => { console.log('Button clicked!'); }">Click me</button>
      

5. Custom Events:

  • Custom Event Handling:

    • Components can emit custom events to communicate with their parent components.
    • Example:

      <!-- Child Component -->
      <button @click="notifyParent">Click me</button>
      
      <script>
        methods: {
          notifyParent() {
            this.$emit('custom-event', 'Hello from child!');
          }
        }
      </script>
      
    ```
    <!-- Parent Component -->
    <child-component @custom-event="handleCustomEvent"></child-component>

    <script>
      methods: {
        handleCustomEvent(message) {
          console.log('Received custom event:', message);
        }
      }
    </script>
    ```
Enter fullscreen mode Exit fullscreen mode

These are the fundamental concepts of event handling in Vue.js. Understanding these concepts will help you create interactive and responsive Vue.js applications.

  • Form Binding : Here you will learn about how to your template will interact with your data, whether how your is fed to a form or how you go from data in your <textarea/> input to a property in an object - Component lifecycle : This is where you will learn about the different series of initialization steps a component goes through when it's created and how you can use them for your advantage, Ex: thanks to onMounted() hook, you can load your table data right when the component is mounted. - Watchers : You can consider them as literal data surveillance dogs. you can program them to make any callback. right after the value of a property changes and they can be configured too. In Vue 3's Composition API, both watch and watchEffect are functions used for reactively watching data sources, but they differ in their behavior and use cases. Here's an explanation of the differences between them:

watch:
The watch function is used to watch one or more reactive data sources and perform side effects or update other reactive data based on the changes. It takes two arguments: a source (reactive data source or getter function) and a callback function.

Example:

import { ref, watch } from 'vue'

const count = ref(0)
const doubled = ref(0)

watch(count, (newCount, oldCount) => {
  doubled.value = newCount * 2
})
Enter fullscreen mode Exit fullscreen mode

In this example, watch observes changes to the count reactive reference and updates the doubled reactive reference with the new doubled value whenever count changes.

The watch function is useful when you need to perform side effects or update other reactive data based on changes to specific data sources.

watchEffect:
The watchEffect function is a more low-level and powerful way to reactively watch data sources. It takes a single function as an argument, and this function is automatically re-executed whenever any of its reactive dependencies (data sources it accesses) change.

Example:

import { ref, watchEffect } from 'vue'

const count = ref(0)
const doubled = ref(0)

watchEffect(() => {
  doubled.value = count.value * 2
})
Enter fullscreen mode Exit fullscreen mode

In this example, watchEffect automatically tracks the reactive dependencies (in this case, count) inside its callback function. Whenever count changes, the callback function is re-executed, and doubled is updated with the new doubled value.

The key difference between watchEffect and watch is that watchEffect automatically tracks dependencies, while watch requires you to explicitly specify the data sources to watch.

watchEffect is useful when you have a complex computation or side effect that depends on multiple reactive data sources, and you don't want to explicitly list all of them in a watch call.

Here are some additional differences between watch and watchEffect:

-- Cleanup: The callback function passed to watchEffect can optionally return a cleanup function, which will be called before the effect is re-executed or the component is unmounted. This is useful for cleaning up side effects like timers or event listeners. In contrast, watch does not provide a built-in mechanism for cleanup.

-- Lazy Initialization: watchEffect is lazy, meaning it will not execute its callback function until its reactive dependencies are accessed for the first time. This can be useful for performance optimization. watch, on the other hand, will execute its callback immediately after the component is mounted.

-- Manual Invalidation: watchEffect provides a way to manually invalidate and re-execute the effect using the watchEffect function's return value (an invalidate function). This can be useful for handling external data sources or manually triggering updates. watch does not provide a similar mechanism.

  • Template Refs : While Vue's declarative rendering model abstracts away most of the direct DOM operations for you, there may still be cases where we need direct access to the underlying DOM elements. To achieve this, we can use the special ref
  • Component Basics here you will learn about:
    • Defining a Component
    • Using a Component
    • Passing Props
    • Listening to Events
    • Content Distribution with Slots
    • Dynamic Components

Top comments (2)

Collapse
 
aloisseckar profile image
Alois Sečkár • Edited

I also remember the reasoning you use in the part about ref/reactive from the days I was learning Vue.js, but Vue team now recommends ref to be used in favor of reactive even for complex structures. The convenience of not having to write .value in script part is paid with several gotchas as discussed in the docs.

Personally I think having these two options with so different behavior, is one of the biggest source of confusion for newcomming devs willing to learn Composition API style. Would be better to drop reactive completely, but I know this is unlikely to happen.

Collapse
 
mrlinxed profile image
Mr. Linxed

Welcome!

I hope you'll share more Vue related content in the future.