Categories
Vue Tips

Vue Tips — Transitions, Routes, and Data

Spread the love

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to create reusable transitions and making requests in a Vue app.

Encapsulated Transition Component

We can encapsulate transitions into its own component so that we can reuse it anywhere.

For instance, we can create a transition component that has the transition component and then reuse it as follows:

styles.css :

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}

index.js :

Vue.component("foo-transition", {
  template: `
  <transition name="fade">
    <slot></slot>
  </transition>
  `
});

new Vue({
  el: "#app",
  data: {
    show: true
  }
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <link type="text/css" rel="stylesheet" href='styles.css'></link>
  </head>
  <body>
    <div id="app">
      <button v-on:click="show = !show">
        Toggle transition
      </button>
      <foo-transition>
        <p v-if='show'>foo</p>
      </foo-transition>
      <foo-transition>
        <p v-if='show'>bar</p>
      </foo-transition>
    </div>
    <script src="index.js"></script>
  </body>
</html>

In the code above, we have the reusable foo-transition component that has a transition component with a slot inside so we can toggle on and off what we want within the foo-transition component with the transition effects applied to it.

Then in index.html , we reused foo-transition by writing:

<foo-transition>
  <p v-if='show'>foo</p>
</foo-transition>
<foo-transition>
  <p v-if='show'>bar</p>
</foo-transition>

Then when we toggle show between true and false , we’ll see both p elements have the fade transition effect applied to it.

Also, we can also use v-bind='$attrs' to bind attributes from parent to child and v-on='$listeners' to pass event listeners from parent to child.

For instance, we can change the example above as follows:

styles.css :

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.foo {
  color: green;
}

index.js :

Vue.component("foo-transition", {
  template: `
  <transition name="fade" v-bind="$attrs" v-on="$listeners">
    <slot></slot>
  </transition>
  `
});

new Vue({
  el: "#app",
  data: {
    show: true
  }
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <link type="text/css" rel="stylesheet" href='styles.css'></link>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle transition
      </button>
      <foo-transition class="foo">
        <p v-if='show'>foo</p>
      </foo-transition>
    </div>
    <script src="index.js"></script>
  </body>
</html>

In the code above, we have v-bind=”$attrs” in transitions . So we’ll get the foo class applied to it if we set the class to foo in foo-transition .

Use Axios for Data Fetching

Vue doesn’t come with its own HTTP client, so to make HTTP requests, we have to add our own. Axios is a good choice since it’s available via CDN and as a Node package.

Also, it’s promise-based so that we won’t have to deal with nested callbacks.

For instance, we can use it as follows:

index.js :

new Vue({
  el: "#app",
  data: {
    info: {}
  },
  async mounted() {
    const { data } = await axios.get(
      "https://api.coindesk.com/v1/bpi/currentprice.json"
    );
    this.info = data;
  }
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <p v-if="info.bpi">
        {{info.bpi['USD'].code}} - {{info.bpi['USD'].rate}}
      </p>
    </div>
    <script src="index.js"></script>
  </body>
</html>

In the code above, we used the Axios library by including it from CDN. Then we get the data in the mounted hook. Since axios.get returns a promise, we can use the async and await syntax to make the request.

An alternative would be the Fetch API, which is similar to Axios, but we don’t have to add a library to use it.

Use vue-router to Handle Client-Side Routing

Vue Router is one of the most commonly used router for Vue apps. It lets us map URLs to components and also get route and query parameters and pass them into our components.

It also supports nested routes and transitions.

A simple example would be the following:

index.js :

const Foo = { template: "<div>foo</div>" };
const Bar = { template: "<div>bar</div>" };

const routes = [
  { path: "/foo", component: Foo },
  { path: "/bar", component: Bar }
];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <router-link to="/foo">Foo</router-link>
      <router-link to="/bar">Bar</router-link>
      <router-view></router-view>
    </div>
    <script src="index.js"></script>
  </body>
</html>

In the code above, we added the Vue Router and then add the router-view to display the route content, which are the components we mapped to.

Then we have the router-link that we can click on to navigate between the routes.

Conclusion

We can create reusable transition components by adding slots inside transition components. To make HTTP requests, we can use the Axios HTTP client to make send requests easy. Finally, we can use Vue Router to map URLs to our components.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *