0👍
You are using the bindings and the emit the wrong way. Right now your App component is emitting an event that no component is listening. And you are trying to use the isActive
property of the ShopList component in the parent.
What you want to do is actually emit an event from the ShopList component and react to that event on the App component. The code would be something like…
var app = new Vue({
el: "#app", // el = element
data: function () {
return {
showListIsActive: false,
};
},
methods: {
toggleShopList() {
this.shopListIsActive = !this.shopListIsActive
},
},
});
Vue.component("shop-list", {
template: `<div class="shop-list">
<transition name="fade">
<div>
<div class="row shop-header">
<h3 class="col-10">Panier</h3>
<a class="col-2" href="#" @on:click="toggle">X</a>
</div>
<div>
<p>votre panier est vide</p>
</div>
</div>
</transition>
</div>`,
methods: {
toggle() {
this.$emit('toggle')
}
},
});
Note the changes:
- isActive moved to the App component as shopListIsActive
- ShopList emits the ‘toggle’ event
Now your app’s template would be:
<div id="app">
<shop-list v-if="shopListIsActive" v-on:toggle="this.toggleShopList">
</shop-list>
<header>
<div class="row">
<div class="col-4">
<img src="https://cdn.shopify.com/s/files/1/0083/4856/5568/files/QUELAFAMILLE.svg?v=1587044097">
</div>
<div class="col-4" id="menu">
<ul>
<li><a href="#">Catalogue</a></li>
<li><a href="#">Look Book</a></li>
<li><a href="#">Mon compte</a></li>
</ul>
</div>
<div class="col-4 shop-cart">
<a v-on:click="toggleShopList"><i class="icon-shopping-cart" style="font-size: 22px;"></i>
Now the App controls if the ShopList component is shown or not and listens to the toggle
event emitted by the ShopList to hide it.
Note that the v-if
directive expect shopListIsActive
to be a property of the element that uses that component, that’s why you have that error saying isActive
is not defined on your code, it’s defined INSIDE the ShopList component but you are using if from outside it.
0👍
You’re misusing the shorthand v-on syntax.
You simply need to change the syntax to:
<a @click="toggle"> </a>
The point of the shorthand is to omit the v-on/on keyword and just use the @
for events and :
for binging
Examples:
<!-- Regular v-on -->
<a v-on:click="coolMethod"> Wow </a>
<!-- Shorthand @[insert-event-name-here] -->
<a @click="coolMethod"> Much </a>
Check out the docs here for more info.
As for your example, I think you’ve got some code pollution going on. I recreated your code with just the method + showing that the @click="toggle"
does work and reach the component’s method. See code below:
<!DOCTYPE html>
<html>
<div id="app">
<div class="shop-list">
<transition name="fade">
<div>
<div class="row shop-header">
<h3 class="col-10">Panier</h3>
<a class="col-2" href="#" @click="toggle">X</a>
</div>
<div>
<p>votre panier est vide</p>
</div>
</div>
</transition>
</div>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: function () {
return {
isActive: false,
};
},
methods: {
toggle() {
console.log("sa marche !");
alert("sa marche !")
},
},
})
</script>
</html>