A Slide-Out component for Vue3

Slide-out components are a popular UI pattern that can significantly enhance user experience by providing a clean and space-efficient way to display additional content. In this detailed guide, we’ll explore the process of building a feature-rich slide-out component using Vue 3. Leveraging the power of Vue 3’s Composition API, we’ll create a versatile and customizable slide-out component that can be seamlessly integrated into various Vue projects.

Introduction to Vue 3 and the Composition API

Vue 3 is the latest version of the Vue.js framework, introducing several enhancements and new features. One notable addition is the Composition API, which offers a more flexible and scalable way to organize and reuse component logic. We’ll leverage the Composition API to build our slide-out component.

Setting Up the Vue 3 Project

Begin by creating a new Vue 3 project using the Vue CLI:

vue create vue3-slide-out-component

Navigate to the project directory:

cd vue3-slide-out-component

Creating the Slide-Out Component

Create a new component for the slide-out functionality. For this example, let’s name it SlideOut.vue:

<!-- SlideOut.vue -->
<template>
  <div class="slide-out" :class="{ 'slide-out--open': isOpen }">
    <div class="slide-out__content">
      <slot></slot>
    </div>
    <div class="slide-out__handle" @click="toggleSlideOut">
      <span></span>
      <span></span>
      <span></span>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  props: {
    isOpen: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, { emit }) {
    const toggleSlideOut = () => {
      emit('update:isOpen', !props.isOpen);
    };

    return { toggleSlideOut };
  },
};
</script>

<style scoped>
/* Component-specific styles here */
.slide-out {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 300px;
  background-color: #fff;
  box-shadow: -5px 0 15px rgba(0, 0, 0, 0.2);
  transition: transform 0.3s ease-in-out;
  transform: translateX(100%);
}

.slide-out--open {
  transform: translateX(0);
}

.slide-out__content {
  padding: 20px;
}

.slide-out__handle {
  position: absolute;
  top: 20px;
  right: -20px;
  width: 40px;
  height: 40px;
  background-color: #007bff;
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.slide-out__handle span {
  height: 2px;
  width: 20px;
  background-color: #fff;
  margin: 2px;
}
</style>

This SlideOut component includes a handle that, when clicked, toggles the state of the slide-out. The isOpen prop controls whether the slide-out is open or closed.

Using the Slide-Out Component

Now, let’s use our SlideOut component in another component. Create a new component (e.g., App.vue) and use the SlideOut component to display content:

<!-- App.vue -->
<template>
  <div id="app">
    <SlideOut :isOpen="isSlideOutOpen" @update:isOpen="updateSlideOutState">
      <div>
        <h2>Slide-Out Content</h2>
        <p>This is some content inside the slide-out component.</p>
      </div>
    </SlideOut>
    <button @click="toggleSlideOut">Toggle Slide-Out</button>
  </div>
</template>

<script>
import { ref } from 'vue';
import SlideOut from './components/SlideOut.vue';

export default {
  components: {
    SlideOut,
  },
  setup() {
    const isSlideOutOpen = ref(false);

    const toggleSlideOut = () => {
      isSlideOutOpen.value = !isSlideOutOpen.value;
    };

    const updateSlideOutState = (value) => {
      isSlideOutOpen.value = value;
    };

    return { isSlideOutOpen, toggleSlideOut, updateSlideOutState };
  },
};
</script>

<style>
/* Global styles here */
body {
  margin: 0;
  font-family: Avenir, Helvetica, Arial, sans-serif;
  background-color: #f8f8f8;
}

#app {
  text-align: center;
  padding: 20px;
}

button {
  padding: 10px;
  font-size: 16px;
  margin-top: 20px;
}
</style>

In this example, we have a button that, when clicked, toggles the state of the slide-out. The content inside the slide-out is specified within the SlideOut component.

A simple library of Slide-Out component for Vue3

There are following steps to use a slide-out component for Vue3

Dependencies

  • Vue.js 3.x
  • Less

Install

NodeJS ENV (commonjs)

npm i @hyjiacan/vue-slideout@3

or

yarn add @hyjiacan/vue-slideout@3

The newest version

<script src="https://cdn.jsdelivr.net/npm/@hyjiacan/vue-slideout/lib/slideout.umd.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@hyjiacan/vue-slideout/lib/slideout.css"/>

Specified version

<script src="https://cdn.jsdelivr.net/npm/@hyjiacan/vue-slideout@<VERSION>/lib/slideout.umd.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@hyjiacan/vue-slideout@<VERSION>/lib/slideout.css"/>

unpkg is also available: instead cdn.jsdelivr.net with unpkg.com. Also, you can use the uncompressed dist by instead slideout.umd.min.js with slideout.umd.js

Usage

Global (recommended)

main.js

import Vue from 'vue'
import Slideout from '@hyjiacan/vue-slideout'
import '@hyjiacan/vue-slideout/lib/slideout.css'

// import Slideout component, and set the defaults props
Vue.use(Slideout, {
  // set default props here
})

In Component

<template>
  <slideout @closing="onClosing" v-model="visible" title="The title">
    <div>content</div>
  </slideout>
</template>
<script>
import Slideout from '@hyjiacan/vue-slideout'
import '@hyjiacan/vue-slideout/lib/slideout.css'

export default {
  name: 'Foobar',
  components: { Slideout },
  data () {
    return {
      visible: false
    }
  },
  methods: {
    onClosing (e) {
      // prevent close and wait
      e.pause = true
      // close after 3 seconds
      setTimeout(() => {
        // assign true to close, do nothing or assign false to cancel close.
        e.resume = true
      }, 3000)
    }
  }
}
</script>

Leave a Comment