My vue component like this :
Vue.component('list-category', {
template: "#lc",
props: ['data', 'category', 'search'],
data() {
return {
open: false,
categoryId: this.category
}
},
mounted() {
let isDataOpen = (d) => d.id === this.categoryId || d.children && d.children.some(isDataOpen);
this.open = isDataOpen(this.data);
},
computed: {
icon() {
return {
'fa-plus': !this.open,
'fa-minus': this.open,
}
},
isFolder() {
return this.data.children && this.data.children.length
},
isShow() {
return this.open ? 'show' : 'hide'
}
},
methods: {
toggle() {
this.open = !this.open
},
filterByCategory(id) {
this.categoryId = id
}
}
})
new Vue({
el: '#app',
data() {
return {
categories: [{
id: 1,
name: 'England',
children: [{
id: 3,
name: 'Chelsea',
children: [{
id: 7,
name: 'Hazard'
},
{
id: 8,
name: 'Morata'
}
]
},
{
id: 4,
name: 'Manchester United',
children: [{
id: 9,
name: 'Pogba'
},
{
id: 10,
name: 'Lukaku'
}
]
}
]
},
{
id: 2,
name: 'Spain',
children: [{
id: 5,
name: 'Real Madrid',
children: [{
id: 11,
name: 'Ronaldo'
},
{
id: 12,
name: 'Bale'
}
]
},
{
id: 6,
name: 'Barcelona',
children: [{
id: 13,
name: 'Messi'
},
{
id: 14,
name: 'Suarez'
}
]
},
]
}
],
category: 7
}
}
})
.active {
background: yellow;
}
.pd-search-filter > .panel-body ul.filter-category {
padding-left: 0;
list-style: none;
margin: 0 -15px 0;
}
.pd-search-filter > .panel-body ul.filter-category > li a {
display: block;
padding: 10px 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pd-search-filter > .panel-body ul.filter-category > li a:last-child {
padding-left: 45px;
}
.pd-search-filter > .panel-body ul.filter-category > li a:focus, .pd-search-filter > .panel-body ul.filter-category > li a:hover {
background-color: #eeeeee;
text-decoration: none;
}
.pd-search-filter > .panel-body ul.filter-category > li a + ul {
padding-left: 0;
list-style: none;
}
.pd-search-filter > .panel-body ul.filter-category > li a + ul > li > a {
padding-left: 30px;
}
.show {
display: block !important;
}
.hide {
display: none !important;
}
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div id="app">
<div class="panel panel-default pd-search-filter">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-circle-o"></i> By Category</h3>
</div>
<div class="panel-body">
<ul class="filter-category" v-for="list in categories">
<list-category :data="list" :category="category"></list-category>
</ul>
</div>
</div>
</div>
<template id="lc">
<li>
<!--parent-->
<a v-if="isFolder" href="javascript:" @click="toggle">
<span class="fa fa-fw" :class="icon"></span> {{data.name}}
</a>
<!--if not folding, we do not need an binding event-->
<a v-else href="javascript:" :title="data.name" :class="{active: data.id === categoryId}" @click="filterByCategory(data.id)"><span class="fa fa-fw fa-circle-o"></span> {{data.name}}</a>
<!--children-->
<ul v-if="isFolder" :class="isShow">
<list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search" :category="categoryId"></list-category>
</ul>
</li>
</template>
Seems you need to see demo and full code
It's like this : http://jsfiddle.net/vxLhbo5m/861/
From demo seen category hazard active. If I click on morata category, it is not active. Whereas I have made the code
How can I solve this problem?
===========================================================================
data(){}which creates a copy of your data and gives it to each component, so any click event is meaningless because that active link is not saved in the same place for all ... if it makes sensethis.$emit('update-active-category', id);infilterByCategorymethod since you are trying to update data from a parent component. Then use@update-active-categorywhen usinglist-categorycomponent in order to update the category in parent app