In Vue.js how do you target/detect the clicked element to perform a basic toggle class?
I've written this which toggles successfully but when you click an a the class is applied to to all li's
HTML
<ul id="app" class="projects">
<li v-bind:class="dyClass">Project A</li>
<li v-bind:class="dyClass">Project B</li>
<li v-bind:class="dyClass">Project C</li>
<li v-bind:class="dyClass">Project D</li> </ul>
JS
new Vue({
el: '#app',
data: {
show: false,
},
computed: {
dyClass: function() {
return {
show: this.show
}
}
}
})
I'm new to Vue.
EDIT.
I managed to get it working with a mix of help from below, but I dont seem to be able to get the toggle effect.
<ul id="app" class="projects">
<li :class="{show:selected == 1}">
<a href="" #click.prevent.stop="selected = 1" >Exposure</a>
</li>
<li :class="{show:selected == 2}">
<a href="" #click.prevent.stop="selected = 2" >Exposure</a>
</li>
<li :class="{show:selected == 3}">
<a href="" #click.prevent.stop="selected = 3" >Exposure</a>
</li>
</ul>
and
new Vue({
el: '#app',
data: {
selected: false,
}
});
You can pass element to function ($event):
:click=dyClass($event) Then in computed:
dyClass: function(event) {
event.target.toggleClass('whatever')
}
As i understand you have some li items and you want to add an active class when a specific li gets clicked.
Solution:
the "html" part:
<div id="app">
<ul class="projects">
<li v-for="project in projects"
:key="project.id"
:class="{ active: project.id === activeProjectId }"
#click="activeProjectId = project.id"
>
{{ project.name }}
</li>
</ul>
</div>
The "vue" part
new Vue({
el: "#app",
data: {
projects: [
{ id: 1, name: 'Project A' },
{ id: 2, name: 'Project B' },
{ id: 3, name: 'Project C' },
{ id: 4, name: 'Project D' },
],
activeProjectId: 1
},
})
Then add some css to the 'active' class.
For more, See the fiddle
Related
<ul class="ulItems" v-for="item in listingItems" :key="item.channels">
<li class="liItems">
{{ item.itemName }}
</li>
</ul>
I want to display an image in cases where the list does not contain an object with that name
If I understood you correctly, try like following snippet:
new Vue({
el: '#demo',
data() {
return {
listingItems: [{itemName: 'aaa', channels: 1}, {itemName: '', channels: 2}, {itemName: 'bbb', channels: 3}],
noNameImg: 'https://picsum.photos/50'
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<ul class="ulItems" v-for="item in listingItems" :key="item.channels">
<li class="liItems" v-if="item.itemName">
{{ item.itemName }}
</li>
<li class="liItems" v-else>
<img :src="noNameImg" />
</li>
</ul>
</div>
Here is an working example https://jsfiddle.net/79epsrmw/
But same in vs code not targeting to item1 sub menu, After passing unique id also.
var app = new Vue({
el: '#app',
data: {
menuItems: [
{
name: 'Item 1',
children: [{name: 'Subitem 1'},{name: 'Subitem 2'},{name: 'Subitem 3'}]
},
{
name: 'Item 2'
}
],
selectedDropdown: 'None'
},
methods: {
setSelectedItem(item) {
this.selectedDropdown = item;
}
},
ready: function() {
$('.dropdown-submenu a.test').on("click", function(e){
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
}
})
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
}
<div class="container" id="app">
<h2>Vue.js multi-level dropdown example</h2>
<p>
Selected element: {{ selectedDropdown }}
</p>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">Dropdown
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li v-for="item in menuItems" v-bind:class="{'dropdown-submenu': item.children}">
<a class="test" tabindex="-1" href="#">{{item.name}}<span class="caret" v-if="item.children"></span></a>
<ul class="dropdown-menu" v-if="item.children">
<li v-for="child in item.children"><a tabindex="-1" href="#" #click="setSelectedItem(child.name)">{{child.name}}</a></li>
</ul>
</li>
</ul>
</div>
</div>
I am getting an error ""Elements in iteration expect to have 'v-bind:key' directives.eslint-plugin-vue
So in order to clear the error i have taken key and passed unique id to it
{{child.name}}
So in order to clear the error i have taken key and passed unique id to it. like :key="child"
Issue is in editor it is working fine, But in vs code after passing unique id, I am unable to select the sub menu in item1.
Check this fiddle
https://jsfiddle.net/negqvmjd/35/
var app = new Vue({
el: '#app',
data: function () {
return {
menuItems: [
{
name: 'Item 1',
children: [{name: 'Subitem 1'},{name: 'Subitem 2'},{name: 'Subitem 3'}]
},
{
name: 'Item 2',
children: []
}
],
selectedDropdown: 'None'
}
},
methods: {
setSelectedItem(item,childLength, bool) {
if(childLength === 0 && bool === false){
this.selectedDropdown = item;
}
else if(childLength !==0 && bool === true){
this.selectedDropdown = item;
}
}
},
ready: function() {
$('.dropdown-submenu a.test').on("click", function(e){
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="container" id="app">
<h2>Vue.js multi-level dropdown example</h2>
<p>
Selected element: {{ selectedDropdown }}
</p>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">Dropdown
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li v-for="item in menuItems" v-bind:class="{'dropdown-submenu': item.children.length}">
<a class="test" tabindex="-1" href="#" #click=setSelectedItem(item.name,item.children.length,false)>{{item.name}}<span class="caret" v-if="item.children.length"></span></a>
<ul class="dropdown-menu" v-if="item.children.length">
<li v-for="child in item.children"><a tabindex="-1" href="#" #click="setSelectedItem(child.name,item.children.length,true)">{{child.name}}</a></li>
</ul>
</li>
</ul>
</div>
</div>
I'm trying to run a function when the cursor is over a list item like so:
<div id="vue-app">
<ul>
<li v-for="item in items" #mouseover="removeItem(item)">{{item}}</li>
</ul>
</div>
new Vue({
el: '#vue-app',
data: {
items: ['meat', 'fruits', 'vegetables'],
},
methods: {
removeItem(value) {
...
}
},
});
however the mouseover event only fires when I click on the list item. What am I not doing correct here?
MouseOver
MouseClicked
Check this working code
new Vue({
el:'#vue-app',
data:{
items:['meat','fruits','vegetables'],
},
methods:{
removeItem(value){
console.log(value);
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.7/vue.js"></script>
<div id="vue-app">
<ul>
<li v-for="item in items" #mouseover="removeItem(item)">{{item}}</li>
</ul>
</div>
I'm trying to follow a tutorial on Vue.js, but the code for the first lesson isn't working for v-repeat. I'm trying to display the data in the tasks object:
<div id="tasks">
<div>
<h1>Tasks</h1>
<ul class="list-group">
<li v-repeat="task: tasks">
{{ task.body }}
</li>
</ul>
</div>
</div>
<script>
new Vue ({
el: '#tasks',
data: {
tasks: [
{ body: 'Go to store', completed: false }
]
}
})
</script>
<li v-for="task in tasks">
v-repeat was deprecated in 1.0:
https://github.com/vuejs/vue/issues/1200
HTML side code
<template name="profPageAuthorSubmit">
<div>
<ul style="list-style-type:none" class="pclProf">
<li><img id="profilePagePic" src="{{profilePagePicture}}"><span class="username">{{authorSubmit}}</span></li>
<li class="accesories">{{a}} Poems</li>
<li class="accesories">{{b}} Short stories</li>
<li class="accesories">{{c}} Followers</li>
<li class="accesories">{{d}} Followings</li>
</ul>
</div>
<div>
<ul style="list-style-type:none" class="pcl">
{{#each Contents}}
<li class="p">
<p class="bucket">
<li><span class="contentType">{{type}}</span></li>
<li><span class="titleBody"><strong>{{{title}}}</strong></span></li>
<li><img class="authorPic" src="{{authorPhoto}}"><span class="authorName">{{author}}</span></li>
<li><span class="createdAtTime">Written at {{createdAt}}</span></li>
<li class="contentMain">{{{content}}}</li>
{{>contentEssentials}}
{{#if editing}}
{{>contentEdit}}
{{/if}}
{{>commentsTemp}}
</p>
</li>
{{/each}}
**{{#if nextPath}}
Load more
{{#unless ready}}
{{> spinner}}
{{/unless}}
{{/if}}**
</ul>
</div>
</template>
Client side code
profileController= RouteController.extend({
template: 'profPageAuthorSubmit',
increment: 10,
contentsLimit: function() {
return parseInt(this.params.contentsLimit) || this.increment;
},
findOptions: function() {
return {sort: {createdAt: -1}, limit: this.contentsLimit()};
},
subscriptions: function() {
this.ContentsSub = Meteor.subscribe('contents', this.findOptions());
return Meteor.subscribe('allUserData');
},
Contents: function() {
var locationArray= location.href.split('/');
var UserId= locationArray[4];
return contentsList.find({createdBy: UserId, anonymous: false}, this.findOptions());
},
data: function() {
var hasMore = this.Contents().count() === this.contentsLimit();
var nextPath = this.route.path({contentsLimit: this.contentsLimit() + this.increment});
console.log("ready");
return {
Contents: this.Contents(),
ready: this.ContentsSub.ready,
nextPath: hasMore ? nextPath : null
};
}
});
Router.map(function(){
Router.route('profPageAuthorSubmit',{
path: '/user/:createdBy/:contentsLimit?',
controller: profileController
});
});
Why is load-more button not showing. I have checked it again and again but still it is not showing. The same thing has worked in other templates.
Basically it is checking whether the contents number is greater than the number displayed, if it is then the load more button should show.
Thanking all
As far as i know, every child of a "ul" tag must be a "li" tag. So the "a" isnt recognized. Try to put the content inside a "li" tag.