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>