Categories
Top Vue Packages

Top Vue Packages for Adding Drag and Drop and Watching Resizing

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 the best packages for adding drag and drop and watching elements resizing to our Vue app.

VueDraggableResizable

VueDraggableResizable is an easy to use the package to let us make comments draggable and resizable.

To use it, we install it by running:

npm i vue-draggable-resizable

Then we can use it by writing:

import Vue from "vue";
import App from "./App.vue";
import VueDraggableResizable from "vue-draggable-resizable";

import "vue-draggable-resizable/dist/VueDraggableResizable.css";

Vue.component("vue-draggable-resizable", VueDraggableResizable);
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

to register the component and add the styles.

Then in our component, we write:

<template>
  <div id="app">
    <div id="draggable">
      <vue-draggable-resizable
        :w="100"
        :h="100"
        [@dragging](http://twitter.com/dragging "Twitter profile for @dragging")="onDrag"
        [@resizing](http://twitter.com/resizing "Twitter profile for @resizing")="onResize"
        :parent="true"
      >
        <p>drag me ({{x}},{{y}})</p>
      </vue-draggable-resizable>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      width: 0,
      height: 0,
      x: 0,
      y: 0
    };
  },
  methods: {
    onResize(x, y, width, height) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
    },
    onDrag(x, y) {
      this.x = x;
      this.y = y;
    }
  }
};
</script>

<style>
#draggable {
  height: 500px;
  width: 500px;
  position: relative;
}
</style>

We have a 500px by 500px div that we can drag and resize thanks to the vue-draggable-resizable component.

The x and y coordinates change and can be listened to with the onDrag handler, which has the latest coordinates in the parameters.

Likewise, we can do the same for resize:

<template>
  <div id="app">
    <div id="draggable">
      <vue-draggable-resizable
        :w="100"
        :h="100"
        [@dragging](http://twitter.com/dragging "Twitter profile for @dragging")="onDrag"
        [@resizing](http://twitter.com/resizing "Twitter profile for @resizing")="onResize"
        :parent="true"
      >
        <p>drag me ({{x}},{{y}})</p>
        <p>size ({{width}}x{{height}})</p>
      </vue-draggable-resizable>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      width: 0,
      height: 0,
      x: 0,
      y: 0
    };
  },
  methods: {
    onResize(x, y, width, height) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
    },
    onDrag(x, y) {
      this.x = x;
      this.y = y;
    }
  }
};
</script>

<style>
#draggable {
  height: 500px;
  width: 500px;
  position: relative;
}
</style>

The onResize method for the coordinates and the size.

Props

It comes with other props like class-name to set the class name.

class-name-draggable to add styles with draggable is enabled.

class-name-resizable lets us style the element when it’s resized.

class-name-resizing lets us add styles when it’s resizing.

class-name-handle styles the handles.

disable-user-select lets us disable user to select.

There are many other props that we can use to style and handle events.

The initial x and y coordinates can also be set with the props of the same name.

vue-resize

We can watch elements being resized with the vue-resize package.

To use it, we install it by running:

npm i vue-resize

Then we register the component by adding:

import Vue from "vue";
import App from "./App.vue";
import "vue-resize/dist/vue-resize.css";
import VueResize from "vue-resize";

Vue.use(VueResize);

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

It comes with styles and the resize-observer component.

Then in our component, we add:

<template>
  <div class="demo">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eu facilisis lorem. In arcu nisl, vulputate id diam eget, ultricies aliquet neque. Phasellus sapien lacus, consectetur ut nisi quis, mattis tincidunt ante. Aliquam ultrices nisl ornare augue laoreet, a vehicula libero consequat. Sed aliquam aliquet turpis, ut sodales elit sodales sit amet. Donec ullamcorper velit neque, in maximus odio tempus eu. Praesent ullamcorper, nibh sodales maximus feugiat, erat tellus condimentum sem, ac convallis tellus diam suscipit tellus. Proin egestas tellus neque. Vestibulum porttitor tempus tellus sit amet volutpat. Sed urna nibh, molestie non pulvinar in, accumsan nec nisl.</p>
    <resize-observer @notify="handleResize"/>
  </div>
</template>

<script>
export default {
  methods: {
    handleResize({ width, height }) {
      console.log("resized", width, height);
    }
  }
};
</script>

<style scoped>
.demo {
  position: relative;
}
</style>

We set the notify handler to handleResize to watch for size changes.

The width and height are in the handler for us to use.

Conclusion

We can use the vue-draggable-resizable package to let us create elements that are draggable and resizable.

The vue-resize package lets us watch for elements being resized.

Categories
Vue 3

Vue 3 — Transition Between Components and Lists

Vue 3 is in beta and it’s subject to change.

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at creating transition effects between components and lists.

Transitioning Between Components

We can transition between components with the transition and component components.

The component component is used for switching between components dynamically by setting their name.

For instance, we can use it by writing:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .bounce-enter-active {
        animation: bounce-in 1.3s;
      }
      .bounce-leave-active {
        animation: bounce-in 1.3s reverse;
      }
      @keyframes bounce-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.8);
        }
        100% {
          transform: scale(1);
        }
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="currentComponent = 'foo'">foo</button>
      <button @click="currentComponent = 'bar'">bar</button>
      <button @click="currentComponent = 'baz'">baz</button>
      <transition name="bounce" mode="out-in">
        <component :is="currentComponent"></component>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            currentComponent: "foo"
          };
        },
        components: {
          foo: {
            template: "<div>foo</div>"
          },
          bar: {
            template: "<div>bar</div>"
          },
          baz: {
            template: "<div>baz</div>"
          }
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We created 3 components, foo , bar and baz .

And we to transition between them, we created 3 buttons to change the component names.

We also have the name prop and to set transition name.

And we also have the transition styles in the style tag.

When we click the buttons, we’ll see a transition effect before we see the content of the new component.

List Transitions

We can add transition effects to lists.

To do this, we can use the transition-group component.

Unlike transition , it renders the actual element.

A span is rendered by default.

We can change this with the tag attribute.

Transition modes aren’t available since we aren’t alternating between mutually exclusive elements.

Elements inside are always required to have a unique key attribute.

CSS transitions classes will be applied to inner elements and not to the container itself.

List Entering/Leaving Transitions

We can add a list enter or leave transitions with the transition-group component.

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .list-enter-active,
      .list-leave-active {
        transition: all 1s ease;
      }
      .list-enter-from,
      .list-leave-to {
        opacity: 0;
        transform: translateY(35px);
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="add">Add</button>
      <button @click="remove">Remove</button>
      <transition-group name="list" tag="div">
        <p v-for="item in items" :key="item">
          {{ item }}
        </p>
      </transition-group>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            items: Array(10)
              .fill()
              .map(() => Math.random()),
            nextNum: 10
          };
        },
        methods: {
          randomIndex() {
            return Math.floor(Math.random() * this.items.length);
          },
          add() {
            this.items.splice(this.randomIndex(), 0, Math.random());
          },
          remove() {
            this.items.splice(this.randomIndex(), 1);
          }
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We created a list from an array of random numbers.

And we added the add and remove buttons to let us add and remove items.

The transition effects are in the style tags.

The effects we added is the opacity change and vertical translation effects.

In the template, we have the transition-group component with the name prop set to list to make that the prefix of the transition class names.

tag is the tag we render for the container.

We added the key prop as required in the p element, which is rendered from the items list.

This way, Vue can tell where each item is and animate them correctly.

Finally, we have the add and remove methods to let us add and remove items from the items array.

randomIndex generates a random index to add or remove items.

Now when we click add or remove, we’ll see the transition effects applied.

Conclusion

We can transition between components and add transition effects to list items.

Categories
Vue 3

Vue 3 — Transitions

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at parts of a transition.

Timing

UI transitions have the timing to let us set the duration of the animation.

We may have different timing for transitions between different states.

If a transition has no intermediate state, then the timing is between 0.1s and 0.4s.

Easing

The easing lets us add some depth to our animation.

Without easing, the animation would be linear and uninteresting.

We want to use ease-out for entrances and and ease-in for exits.

Enter & Leave Transitions

We can use the transition wrapper component to add our enter and leave transitions.

For instance, we can add a simple transition with the transition component by writing:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .fade-enter-active,
      .fade-leave-active {
        transition: opacity 1s ease;
      }

      .fade-enter-from,
      .fade-leave-to {
        opacity: 0;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition name="fade">
        <p v-if="show">hello</p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We add the transition to the p element by wrapping it with the transition component.

Then we set the name prop of it to the prefix of the classes we’ll use for styling the transition.

We set it to fade , so all the transition classes starts with fade- .

We have the fade-enter-active , fade-leave-active classes to show a fading effect.

And we have the fade-enter-from and fade-leave-to classes to make the content transparent to maker the content disappear when show is false .

Vue will detect whether the target element has CSS transitions or animations applied.

CSS transition classes will be added or removed at appropriate timings.

If no CSS transitions or animations are detected and no JavaScript hooks are provided, then ODM operations will be run on the next browser animation frame.

Transition Classes

There’re several transition classes that we can apply styles to.

v-enter-from is applied before the element is inserted and remove one frame after the element is inserted.

v-enter-active is applied before the animation is inserted and removed when the transition or animation finishes.

v-enter-to is added one frame after the element is inserted and removed when the transition or animation finishes.

v-leave-from is applied immediately when a leaving transition is triggered and removed after 1 frame.

v-leave-active is applied during the entire leaving phase.

It’s added immediately when the leave transition is triggered and removed when the transition or animation finishes.

v-leave-to is added one frame after a leaving transition is triggered and removed when the transition or animation finishes.

Conclusion

We can add transitions easily with the transition component.

Once we used that, we can add CSS style to apply the effects we want.

Categories
Vue 3

Vue 3 — Transitions and Animations

Vue 3 is in beta and it’s subject to change.

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at CSS transitions and animations.

CSS Transitions

The transition a component is most commonly used with CSS transitions.

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .fade-enter-active {
        transition: all 0.3s ease-out;
      }

      .fade-leave-active {
        transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
      }

      .fade-enter-from,
      .fade-leave-to {
        transform: translateX(20px);
        opacity: 0;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition name="fade">
        <p v-if="show">hello</p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We have the transition component that has the name prop to set the prefix for the transition class names.

We set the transition property in the CSS to look let us set the transition effects.

ease-out is for entering effects.

And cubic-bezier is our easing curve to adjust the speed of the transition as it progresses.

CSS Animations

CSS animations are applied in the same way as CSS transitions.

The different between transitions and animations is that v-enter-from isn’t removed immediately after the element is inserted.

It’s instead removed after the animationend event is triggered.

For instance, we can create animations with keyframes by writing:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .bounce-enter-active {
        animation: bounce-in 1.5s;
      }
      .bounce-leave-active {
        animation: bounce-in 1.5s reverse;
      }
      @keyframes bounce-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(1);
        }
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition name="bounce">
        <p v-if="show">hello</p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We have the keyframes in our CSS so that we can define our animation effects at the stages we want.

We have a transform effect during the start, when it’s halfway through, and when it ends.

Custom Transition Classes

We can set custom transition classes instead of using the preset class names.

To do that, we just have to set a few props.

The props we can set are:

  • enter-from-class
  • enter-active-class
  • enter-to-class
  • leave-from-class
  • leave-active-class
  • leave-to-class

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .enter-active {
        animation: bounce-in 1.5s;
      }
      .leave-active {
        animation: bounce-in 1.5s reverse;
      }
      @keyframes bounce-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(1);
        }
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition
        enter-active-class="enter-active"
        leave-active-class="leave-active"
      >
        <p v-if="show">hello</p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We have the enter-active and leave-active classes to instead of the default class names because we set the enter-active-clas and leave-active-class props.

They override the default class names.

Conclusion

We can change the name of animations and transitions.

There’s a slight difference between transitions and animations.

Categories
Vue 3

Vue 3 — Transition Modes

Vue 3 is in beta and it’s subject to change.

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at creating various transition effects.

Transitions on Initial Render

We can apply a transition on initial render of a node with the appear attribute.

For instance, we can use it by writing:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <title>App</title>  
    <script src="https://unpkg.com/vue@next"></script>  
    <style>  
      .bounce-enter-active {  
        animation: bounce-in 1.3s;  
      }  
      .bounce-leave-active {  
        animation: bounce-in 1.3s reverse;  
      }  
      @keyframes bounce-in {  
        0% {  
          transform: scale(0);  
        }  
        50% {  
          transform: scale(1.8);  
        }  
        100% {  
          transform: scale(1);  
        }  
      }  
    </style>  
  </head>  
  <body>  
    <div id="app">  
      <transition name="bounce" appear>  
        <p>hello</p>  
      </transition>  
    </div>  
    <script>  
      const app = Vue.createApp({});  
      app.mount("#app");  
    </script>  
  </body>  
</html>

We just add the appear attribute to our transition component to make the transition appear when we load the element.

Transitioning Between Elements

We can add a transition between elements that are with the v-if and v-else directives.

For example, we can write:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <title>App</title>  
    <script src="https://unpkg.com/vue@next"></script>  
    <style>  
      .bounce-enter-active {  
        animation: bounce-in 1.3s;  
      }  
      .bounce-leave-active {  
        animation: bounce-in 1.3s reverse;  
      }  
      @keyframes bounce-in {  
        0% {  
          transform: scale(0);  
        }  
        50% {  
          transform: scale(1.8);  
        }  
        100% {  
          transform: scale(1);  
        }  
      }  
    </style>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="show = !show">toggle</button>  
      <transition name="bounce">  
        <p v-if="show">hello</p>  
        <p v-else>bye</p>  
      </transition>  
    </div>  
    <script>  
      const app = Vue.createApp({  
        data() {  
          return {  
            show: false  
          };  
        }  
      });  
      app.mount("#app");  
    </script>  
  </body>  
</html>

We create a transition effect that transitions between the 2 p elements in the transition component.

The transition automatically with the v-if and v-else directives.

We can also transition between any number of elements.

For example, we can write:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <title>App</title>  
    <script src="https://unpkg.com/vue@next"></script>  
    <style>  
      .bounce-enter-active {  
        animation: bounce-in 0.8s;  
      }  
      .bounce-leave-active {  
        animation: bounce-in 0.8s reverse;  
      }  
      @keyframes bounce-in {  
        0% {  
          transform: scale(0);  
        }  
        50% {  
          transform: scale(1.8);  
        }  
        100% {  
          transform: scale(1);  
        }  
      }  
    </style>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="count++">increment</button>  
      <transition name="bounce">  
        <p v-if="count % 3 === 0" key="0">foo</p>  
        <p v-else-if="count % 3 === 1" key="1">bar</p>  
        <p v-else key="2">baz</p>  
      </transition>  
    </div>  
    <script>  
      const app = Vue.createApp({  
        data() {  
          return {  
            count: 0  
          };  
        }  
      });  
      app.mount("#app");  
    </script>  
  </body>  
</html>

We have the v-else-if and v-else directives to make sure that only one is rendered at the same time.

This way, we can keep using the transition component to animate between multiple elements.

Transition Modes

If we deal with more complex animations we can set the mode prop to set the transition effect that’s run.

By default, the in-out and out-in transitions are run simultaneously.

With this prop, we can make our component apply one effect or the other.

Usually, the out-in mode is what we want.

For example, we can write:

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <title>App</title>  
    <script src="https://unpkg.com/vue@next"></script>  
    <style>  
      .bounce-enter-active {  
        animation: bounce-in 1.3s;  
      }  
      .bounce-leave-active {  
        animation: bounce-in 1.3s reverse;  
      }  
      @keyframes bounce-in {  
        0% {  
          transform: scale(0);  
        }  
        50% {  
          transform: scale(1.8);  
        }  
        100% {  
          transform: scale(1);  
        }  
      }  
    </style>  
  </head>  
  <body>  
    <div id="app">  
      <button @click="show = !show">toggle</button>  
      <transition name="bounce" mode="out-in">  
        <p v-if="show">hello</p>  
        <p v-else>bye</p>  
      </transition>  
    </div>  
    <script>  
      const app = Vue.createApp({  
        data() {  
          return {  
            show: false  
          };  
        }  
      });  
      app.mount("#app");  
    </script>  
  </body>  
</html>

With the mode prop set, we won’t see multiple elements being animated at the same time.

Conclusion

We can create transitions between multiple elements with a few props and directives.