Mobile applications often require intuitive and visually appealing navigation systems to enhance the user experience. In this hands-on guide, we’ll explore the creation of a simple yet effective Vue.js mobile nested menu UI component. The component will feature smooth slide animations, providing users with an engaging and seamless navigation experience.
Setting Up the Vue Project:
Begin by creating a new Vue project using the Vue CLI. If you haven’t installed it, run:
npm install -g @vue/cli
Create a new project:
vue create mobile-nested-menu
cd mobile-nested-menu
Designing the NestedMenu Component:
- Create the
NestedMenu.vue
component:
<template>
<div class="nested-menu" :class="{ 'menu-open': isMenuOpen }">
<div class="menu-header" @click="toggleMenu">
<span>{{ isMenuOpen ? 'Close Menu' : 'Open Menu' }}</span>
</div>
<transition name="slide">
<div v-if="isMenuOpen" class="menu-content">
<ul>
<li v-for="category in menuData" :key="category.id" @click="selectCategory(category)">
{{ category.name }}
<ul v-if="category.subcategories.length > 0">
<li v-for="subcategory in category.subcategories" :key="subcategory.id" @click="selectSubcategory(subcategory)">
{{ subcategory.name }}
</li>
</ul>
</li>
</ul>
</div>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
isMenuOpen: false,
menuData: [
{ id: 1, name: 'Category 1', subcategories: [{ id: 11, name: 'Subcategory 1.1' }, { id: 12, name: 'Subcategory 1.2' }] },
{ id: 2, name: 'Category 2', subcategories: [] },
{ id: 3, name: 'Category 3', subcategories: [{ id: 31, name: 'Subcategory 3.1' }] },
],
};
},
methods: {
toggleMenu() {
this.isMenuOpen = !this.isMenuOpen;
},
selectCategory(category) {
console.log(`Selected Category: ${category.name}`);
},
selectSubcategory(subcategory) {
console.log(`Selected Subcategory: ${subcategory.name}`);
// Additional logic, e.g., navigate to a page or perform an action
},
},
};
</script>
<style scoped>
.nested-menu {
position: relative;
width: 100%;
}
.menu-header {
background-color: #3498db;
color: #fff;
padding: 10px;
text-align: center;
cursor: pointer;
}
.menu-content {
background-color: #f4f4f4;
overflow: hidden;
}
.menu-content ul {
list-style: none;
padding: 0;
}
.menu-content li {
padding: 10px;
cursor: pointer;
}
.menu-content li:hover {
background-color: #e0e0e0;
}
.slide-enter-active, .slide-leave-active {
transition: transform 0.5s;
}
.slide-enter, .slide-leave-to {
transform: translateX(-100%);
}
</style>
Using the NestedMenu Component in App.vue:
<template>
<div id="app">
<NestedMenu />
</div>
</template>
<script>
import NestedMenu from './components/NestedMenu.vue';
export default {
components: {
NestedMenu,
},
};
</script>
<style>
#app {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #ecf0f1;
margin: 0;
}
</style>
Explanation of the NestedMenu Component:
- The template section includes a header to toggle the menu visibility and a transition-wrapped menu content with nested categories and subcategories.
- The script section defines data for menu states and structures, as well as methods to handle menu interactions.
- The scoped styles define the appearance and smooth slide animation for the nested menu.
Running the Application:
Run the following commands to see the nested menu in action:
npm install
npm run serve
Visit http://localhost:8080
in your browser to interact with the mobile nested menu component.
Complete implementation of a simple hands-on mobile nested menu UI component with a smooth slide animation
vue-nested-menu
A simple hands-on mobile nested menu UI component with a smooth slide animation.
Installation
Yarn / NPM
$ yarn add vue-nested-menu
main.js
import VueNestedMenu from 'vue-nested-menu'; Vue.use(VueNestedMenu);
Usage
Basic
index.html
<div id="app"> <vue-nested-menu :source="menu"></vue-nested-menu> </div>
main.js
import VueNestedMenu from 'vue-nested-menu'; Vue.use(VueNestedMenu) new Vue({ el: '#app', data: { menu: { title: '首頁', children: [ { title: `Today's Deals`, link: `/today`, children: [], }, { title: `Shop By Department`, children: [ { title: `Amazon Music`, link: `/music`, children: [], }, { title: `CDs and Vinyl`, link: `/cds`, children: [], }, ], }, ], }, }, });
Single File Component
app.js
import VueNestedMenu from 'vue-nested-menu'; Vue.use(VueNestedMenu); // ...
MyMenu.vue
<template> <vue-nested-menu :source="menu" /> </template> <script> export default { data() { return { menu: { // your menu data }, }; }, }; </script>
Styling
You can use following classes for your own customizations
default style
.Menu__header { display: flex; align-items: center; padding-left: 35px; height: 50px; color: #fff; font-size: 16px; background-color: #232f3e; cursor: pointer; .arrow { padding-top: 2px; fill: #fff; margin-right: 10px; width: 10px; height: 100%; display: flex; align-items: center; } } .Menu__list { list-style: none; padding-bottom: 2px; .separator { border-bottom: 1px solid #d5dbdb; padding: 2px 0 0 0; margin: 0; } } .Menu__item { color: #4a4a4a; padding-left: 35px; height: 45px; display: flex; align-items: center; cursor: pointer; a { color: #4a4a4a; text-decoration: none; } .arrow { padding-top: 2px; padding-left: 15px; display: flex; align-items: center; width: 10px; height: 100%; } }