'How rewrite menu on Vue?
I'm learning Vue. I wrote a menu script on jquery. Now I want to rewrite this script on Vue. The menu should always be on one line. If the item of menu does not fit, add a class 'is-hidden'. How to add a method so that a class that does not fit menu items is added 'is-hidden'?
Jquery variant menu:
$(function() {
var base = '.menu';
$(base).each(function() {
var component = $(this);
var menuItems = component.children(base + '__item');
function calc() {
var menuWidth = Math.floor(component.innerWidth());
var menuItemsCounter = 0;
menuItems.each(function(i, el) {
var menuItemWidth = Math.floor($(el).outerWidth());
if (menuItemsCounter + menuItemWidth > menuWidth - 10) {
$(el).addClass('is-hidden')
} else {
$(el).removeClass('is-hidden')
menuItemsCounter += menuItemWidth;
}
});
}
calc();
$(window).on('resize', calc);
});
});
body {
margin: 0;
}
.menu {
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0;
list-style-type: none;
background-color: black;
}
.menu a {
display: block;
color: white;
text-decoration: none;
padding: 12px 20px;
border: 1px solid;
}
.is-hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li class="menu__item">
<a href="#">Vue</a>
</li>
<li class="menu__item">
<a href="#">Angular</a>
</li>
<li class="menu__item">
<a href="#">React</a>
</li>
<li class="menu__item">
<a href="#">HTML</a>
</li>
<li class="menu__item">
<a href="#">CSS</a>
</li>
<li class="menu__item">
<a href="#">Javascript</a>
</li>
<li class="menu__item">
<a href="#">C#</a>
</li>
<li class="menu__item">
<a href="#">C++</a>
</li>
<li class="menu__item">
<a href="#">Python</a>
</li>
<li class="menu__item">
<a href="#">Java</a>
</li>
<li class="menu__item">
<a href="#">Ruby</a>
</li>
<li class="menu__item">
<a href="#">PHP</a>
</li>
<li class="menu__item">
<a href="#">Laravel</a>
</li>
<li class="menu__item">
<a href="#">Chrome</a>
</li>
<li class="menu__item">
<a href="#">Firefox</a>
</li>
<li class="menu__item">
<a href="#">Webpack</a>
</li>
<li class="menu__item">
<a href="#">Gulp</a>
</li>
<li class="menu__item">
<a href="#">Grunt</a>
</li>
</ul>
Vue variant menu:
const menu = {
data() {
return {
menu: [
{ title: 'Vue' },
{ title: 'Angular' },
{ title: 'React' },
{ title: 'HTML' },
{ title: 'CSS' },
{ title: 'Javascript' },
{ title: 'C#' },
{ title: 'C++' },
{ title: 'Python' },
{ title: 'Java' },
{ title: 'Ruby' },
{ title: 'PHP' },
{ title: 'Laravel' },
{ title: 'Chrome' },
{ title: 'Firefox' },
{ title: 'Webpack' },
{ title: 'Gulp' },
{ title: 'Grunt' },
{ title: 'Vue' },
{ title: 'Angular' },
{ title: 'React' },
{ title: 'HTML' },
{ title: 'CSS' },
{ title: 'Javascript' },
{ title: 'C#' },
{ title: 'C++' },
{ title: 'Python' },
{ title: 'Java' },
{ title: 'Ruby' },
{ title: 'PHP' },
{ title: 'Laravel' },
{ title: 'Chrome' },
{ title: 'Firefox' },
{ title: 'Webpack' },
{ title: 'Gulp' },
{ title: 'Grunt' },
],
menuWidth: 0,
}
},
methods: {
currentLastVisibleItemIndex() {
return this.menu.length - 1;
},
updateWidth: function () {
this.menuWidth = window.innerWidth;
},
calc: function () {
// this.menu.forEach((el, index) => {
// console.log(el, this.$refs.menu[index]);
// });
}
},
computed: {
},
created() {
window.addEventListener("resize", this.updateWidth);
this.updateWidth();
this.calc();
},
}
Vue.createApp(menu).mount('#app')
body {
margin: 0;
}
.menu {
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0;
list-style-type: none;
background-color: black;
}
.menu a {
display: block;
color: white;
text-decoration: none;
padding: 12px 20px;
border: 1px solid;
}
.is-hidden {
display: none;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="app" class="app">
<ul class="menu">
<li v-for="item in menu" :key="item.title" ref="menu">
<a href="#">{{item.title}}</a>
</li>
</ul>
<p>
<b>Menu width:</b> {{menuWidth}}
</p>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
