Target clicked element in Vue - javascript

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

Vue - v-if no item with that name in the list then show an image

<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>

Unable to select subitem from dropdown in Vuejs?

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>

mouseover event not firing till clicked on Google Chrome

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>

Vue.js v-repeat not working

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

My load more button is not showing despite everything being correct according to me

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.

Categories