Vue 3 comes with a parcel of curiously unused highlights and changes to a few of the existing ones that are pointed at making advancement with the system a parcel simpler and viable. In this article, we’re reaching to take a look at a few of these modern highlights and how to urge begun with them. We’re too going be taking a see at a few of the changes done to the existing highlights.

With the discharge of Vue 3, designers got to make the overhaul from Vue 2 because it comes with a modest bunch of modern highlights that are super accommodating in building easy-to-read and viable components and made strides ways to structure our application in Vue. We’re reaching to be taking a see at a few of these highlights in this article.

At the conclusion of this instructional exercise, the perusers will;

  • Know about provide / inject and how to use it.
  • Have a basic understanding of Teleport and how to use it.
  • Know about Fragments and how to go about using them.
  • Know about the changes made to the Global Vue API.
  • Know about the changes made to the Events API.

This article is pointed at those that have a legitimate understanding of Vue 2.x. You’ll discover all the code utilized in this case in Github

Provide / inject

In Vue 2.x, we had props that made it simple to pass information (string, clusters, objects, etc) from a parent component specifically to its children component. But amid improvement, we regularly found occasions where we required to pass information from the parent component to a profoundly settled component which was more troublesome to do with props. This come about within the utilize of Vuex Store, Event Hub, and in some cases passing information through the profoundly settled components. Let’s see at a straightforward app;

It is important to note that Vue 2.2.0 also came with provide / inject which was not recommended to use in generic application code.

# parentComponent.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Vue 3 is liveeeee!" :color="color" />
    <select name="color" id="color" v-model="color">
      <option value="" disabled selected> Select a color</option>
      <option :value="color" v-for="(color, index) in colors" :key="index">{{
        color
      }}</option></select
    >
  </div>
</template>
<script>
  import HelloWorld from "@/components/HelloWorld.vue";
  export default {
    name: "Home",
    components: {
      HelloWorld,
    },
    data() {
      return {
        color: "",
        colors: ["red", "blue", "green"],
      };
    },
  };
</script>
# childComponent.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <color-selector :color="color"></color-selector>
  </div>
</template>
<script>
  import colorSelector from "@/components/colorComponent.vue";
  export default {
    name: "HelloWorld",
    components: {
      colorSelector,
    },
    props: {
      msg: String,
      color: String,
    },
  };
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h3 {
    margin: 40px 0 0;
  }
  ul {
    list-style-type: none;
    padding: 0;
  }
  li {
    display: inline-block;
    margin: 0 10px;
  }
  a {
    color: #42b983;
  }
</style>
# colorComponent.vue

<template>
  <p :class="[color]">This is an example of deeply nested props!</p>
</template>
<script>
  export default {
    props: {
      color: String,
    },
  };
</script>
<style>
  .blue {
    color: blue;
  }
  .red {
    color: red;
  }
  .green {
    color: green;
  }
</style>

Here, we have a landing page with a dropdown containing a list of colors and we’re passing the chosen color to childComponent.vue as a prop. This child component moreover contains a msg prop that acknowledges a content to display within the format segment. At last, this component features a child component (colorComponent.vue) that acknowledges a color prop from the parent component which is utilized in deciding the course for the content in this component. Usually an illustration of passing information through all the components.

But with Vue 3, we will do this in a cleaner and brief way utilizing the unused Provide and infuse combine. As the title infers, we use provide as either a work or an question to form information accessible from a parent component to any of its settled component in any case of how profoundly settled such a component is. We make utilize of the protest frame when passing hard-coded values to provide like this;

# parentComponent.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Vue 3 is liveeeee!" :color="color" />
    <select name="color" id="color" v-model="color">
      <option value="" disabled selected> Select a color</option>
      <option :value="color" v-for="(color, index) in colors" :key="index">{{
        color
      }}</option></select
    >
  </div>
</template>
<script>
  import HelloWorld from "@/components/HelloWorld.vue";
  export default {
    name: "Home",
    components: {
      HelloWorld,
    },
    data() {
      return {
        colors: ["red", "blue", "green"],
      };
    },
    provide: {
      color: 'blue'
    }
  };
</script>

But for instances where you need to pass a component instance property to provide, we use the function mode so this is possible;

# parentComponent.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Vue 3 is liveeeee!" />
    <select name="color" id="color" v-model="selectedColor">
      <option value="" disabled selected> Select a color</option>
      <option :value="color" v-for="(color, index) in colors" :key="index">{{
        color
      }}</option></select
    >
  </div>
</template>
<script>
  import HelloWorld from "@/components/HelloWorld.vue";
  export default {
    name: "Home",
    components: {
      HelloWorld,
    },
    data() {
      return {
        selectedColor: "blue",
        colors: ["red", "blue", "green"],
      };
    },
    provide() {
      return {
        color: this.selectedColor,
      };
    },
  };
</script>

Since we don’t require the color props in both the childComponent.vue and colorComponent.vue, we’re getting freed of it. The great thing approximately utilizing provide is that the parent component does not got to know which component needs the property it is giving.

To form utilize of this within the component that needs it in this case, colorComponent.vue we do this;

# colorComponent.vue

<template>
  <p :class="[color]">This is an example of deeply nested props!</p>
</template>
<script>
  export default {
    inject: ["color"],
  };
</script>
<style>
  .blue {
    color: blue;
  }
  .red {
    color: red;
  }
  .green {
    color: green;
  }
</style>

Here, we utilize inject which takes in an cluster of the desired factors the component needs. In this case, we as it were require the color property so we only pass that. After that, we are able utilize the color the same way we utilize it when utilizing props.

We might take note that in the event that we attempt to choose a modern color utilizing the dropdown, the color does not update in colorComponent.vue and this is often since by default the properties in provide are not receptive. To Settle that, we make utilize of computed strategy.

# parentComponent.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Vue 3 is liveeeee!" />
    <select name="color" id="color" v-model="selectedColor">
      <option value="" disabled selected> Select a color</option>
      <option :value="color" v-for="(color, index) in colors" :key="index">{{
        color
      }}</option></select
    >
  </div>
</template>
<script>
  import HelloWorld from "@/components/HelloWorld.vue";
  import { computed } from "vue";
  export default {
    name: "Home",
    components: {
      HelloWorld,
    },
    data() {
      return {
        selectedColor: "",
        todos: ["Feed a cat", "Buy tickets"],
        colors: ["red", "blue", "green"],
      };
    },
    provide() {
      return {
        color: computed(() => this.selectedColor),
      };
    },
  };
</script>

Here, we purport computed and pass our selectedColor so that it can be receptive and overhaul as the client chooses a distinctive color. Once you pass a variable to the computed strategy it returns an protest which contains a value. This property holds the esteem of your variable so for this case, we would got to upgrade colorComponent.vue to see like this;

# colorComponent.vue

<template>
  <p :class="[color.value]">This is an example of deeply nested props!</p>
</template>
<script>
  export default {
    inject: ["color"],
  };
</script>
<style>
  .blue {
    color: blue;
  }
  .red {
    color: red;
  }
  .green {
    color: green;
  }
</style>

Here, we alter color to color.value to speak to the alter after making color responsive utilizing the computed strategy. At this point, the course of the content in this component would continuously alter at whatever point selectedColor changes within the parent component.

Teleport

There are occasions where we make components and put them in one portion of our application since of the rationale the app employments but are aiming to be shown in another portion of our application. A common case of this would be a modular or a popup that’s implied to display and cover the full screen. Whereas we are able make a workaround for this utilizing CSS’s position property on such components, with Vue 3, able to too do utilizing utilizing Teleport.

Teleport permits us to require a component out of its unique position in a archive, from the default #app holder Vue apps are wrapped in and move it to any existing component on the page it’s being utilized. A great case would be utilizing Teleport to move an header component from interior the #app div to an header It is important to note that you just can as it were Teleport to components that are existing exterior of the Vue DOM.

The Teleport component acknowledges two props that decide the behavior of this component and they are;

  • to This prop acknowledges either a course title, an id, an component or a data-* property. We will too make this esteem energetic by passing a :to prop as restricted to and alter the Teleport component dynamically.
  • :disabled This prop acknowledges a Boolean and can be utilized to flip the Teleport highlight on an component or component. This will be valuable for powerfully changing the position of an component.

An ideal example of using Teleport looks like this;

# index.html**

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
    <title>
        <%= htmlWebpackPlugin.options.title %>
    </title>
</head>
<!-- add container to teleport to -->
<header class="header"></header>
<body>
    <noscript>
      <strong
        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
        properly without JavaScript enabled. Please enable it to
        continue.</strong
      >
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
</body>
</html>

Within the default index.html record in your Vue app, we include an header component since we need to Teleport our header component to that point in our app. We too included a lesson to this component for styling and for simple referencing in our Teleport component.

# Header.vue**

<template>
  <teleport to="header">
    <h1 class="logo">Vue 3 🥳</h1>
    <nav>
      <router-link to="/">Home</router-link>
    </nav>
  </teleport>
</template>
<script>
  export default {
    name: "app-header",
  };
</script>
<style>
  .header {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .logo {
    margin-right: 20px;
  }
</style>

Here, we make the header component and include a symbol with a connect to the homepage on our app. We too include the Teleport component and grant the to prop a esteem of header since we need this component to render interior this component. At long last, we moment this component into our app;

# App.vue

<template>
  <router-view />
  <app-header></app-header>
</template>
<script>
  import appHeader from "@/components/Header.vue";
  export default {
    components: {
      appHeader,
    },
  };
</script>

In this file, we import the header component and place it in the template so it can be visible in our app.

Now if we inspect the element of our app, we would notice that our header component is inside the headerelement;