2017-10-13 6 views
0

J'ai une page d'exploration dans VueJS (voir ci-dessous) et celle-ci contient des composants enfants appelés toggle-tiles et ceux-ci se présentent comme des grilles. Ce que je veux faire, c'est quand on clique sur l'un de ces "toggle-tiles", il a une classe active appliquée que vous pouvez voir à partir de mon code ci-dessous, mais où je suis en train de résoudre un problème.Basculer la classe active entre les composants enfant VueJS

Si une classe est active, je souhaite que la classe active soit supprimée pour le reste d'entre eux. Donc, un seul peut être actif à la fois. Actuellement, ils sont tous actifs lorsque je clique dessus.

S'il vous plaît voir mon code ci-dessous.

<template> 
    <div> 
    <section class="explore"> 
     <div class="explore__banner"> 
     <img src="/static/img/placeholder-banner.jpg" alt="" /> 
     </div> 
     <div class="in"> 
     <div class="explore__intro"> 
      <div class="in"> 
      <h2 class="heading heading--uppercase heading--borderbottom">EXPLORE</h2> 
      <p>Once-in-a-lifetime experiences, art exhibitions, culinary adventures and family fun. Stay inspired and discover 
       your own Algarve.</p> 
      </div> 
     </div> 
     <div class="explore__filters"> 
      <div class="in"> 
      <ul class="list list--inline list--uppercase"> 
       <li> 
       <a href="#">all</a> 
       </li> 
       <li> 
       <a href="#">experiences</a> 
       </li> 
       <li> 
       <a href="#">what's on</a> 
       </li> 
       <li> 
       <a href="#">family</a> 
       </li> 
       <li> 
       <a href="#">food</a> 
       </li> 
       <li> 
       <a href="#">hotel amenities</a> 
       </li> 
      </ul> 
      </div> 
     </div> 
     <div class="explore__blocks"> 
      <div class="in"> 
      <toggle-tile @toggle-active="toggleTile" :showtile="isActive"></toggle-tile> 
      <toggle-tile @toggle-active="toggleTile" :showtile="isActive"></toggle-tile> 
      <toggle-tile @toggle-active="toggleTile" :showtile="isActive"></toggle-tile> 
      </div> 
     </div> 
     </div> 
    </section> 
    <room-builder></room-builder> 
    <offer-carousel :offers="offers"></offer-carousel> 
    </div> 
</template> 

<script> 
    import OfferCarousel from '@/components/OfferCarousel' 
    import RoomBuilder from '@/components/RoomBuilder' 
    import ToggleTile from '@/components/ToggleTile' 
    export default { 
    name: "Explore", 
    components: { 
     'offer-carousel': OfferCarousel, 
     'room-builder': RoomBuilder, 
     'toggle-tile': ToggleTile, 
    }, 
    data() { 
     return { 
     isActive: false, 
     offers: [{ 
      image: '/static/img/placeholder-offer.jpg', 
      active: true, 
      captionText: 'SPECIAL OFFER HEADING', 
      buttonText: 'read more', 
      buttonUrl: '#', 
      opacity: 1, 
      id: 1 
      }, 
      { 
      image: '/static/img/placeholder-offer.jpg', 
      active: false, 
      captionText: 'SPECIAL OFFER HEADING', 
      buttonText: 'read more', 
      buttonUrl: '#', 
      opacity: 0, 
      id: 2 
      } 
     ] 
     } 
    }, 
    methods: { 
     toggleTile: function() { 
     console.log("clicked"); 
     } 
    } 
    } 

</script> 


<template> 
    <div class="block" v-on:click="toggleState" v-bind:class="{active: showBlock }"> 

    <div class="in"> 
     <div class="block__image"> 
     <img src="/static/img/block-placeholder.jpg" alt="" /> 
     <div class="block__image--hover"> 
      <img src="/static/img/svg/open.svg" alt="" /> 
     </div> 
     </div> 
     <div class="block__title"> 
     <div class="in"> 
      <h6 class="heading heading--uppercase">EXPERIENCES</h6> 
      <h3>SUMMER TREATMENTS AT CONRAD SPA</h3> 
     </div> 
     </div> 
    </div> 
    <div class="block__panel"> 
     <div class="in"> 
     <div class="panel__close"> 
      <img src="/static/img/svg/cross.svg" alt="" /> 
     </div> 
     <div class="panel__gallery"> 
      <basic-carousel :images="images"></basic-carousel> 
     </div> 
     <div class="panel__content"> 
      <h6 class="heading heading--uppercase">RIA FORMOSA NATURAL PARK</h6> 
      <p>Spend the day with a local clam picker. A real life adventure on a traditional fisherman’s wooden boat, discovering 
      ancient clam picking secrets. You’ll also visit an oyster bank with oyster degustation and local sparkling wine. 
      </p> 
      <h6 class="heading heading--uppercase">WHEN?</h6> 
      <p>Daily, depending on the tide. Check when booking. 
      </p> 
      <h6 class="heading heading--uppercase">HOW LONG WILL IT TAKE? 
      </h6> 
      <p>Approximately 3 hours including transfer time.</p> 
      <h6 class="heading heading--uppercase">HOW MUCH WILL IT COST?</h6> 
      <p>€250,00 for up to 4 guests. €50 per additional guest. Free for children up to 6 years old. Maximum 12 guests. Return 
      transfers to Faro beach: €62.50 for up to four guests. €87.50 for 5-8 guests. Must be booked in advance. 
      </p> 
      <h6 class="heading heading--uppercase">WHAT’S INCLUDED?</h6> 
      <p>Clam picking equipment, waterproof boots (on request, depending on sizes), oyster tasting & sparkling wine. Don’t 
      forget to bring sunscreen, swimming costumes and flip flops. 
      </p> 
     </div> 
     </div> 
    </div> 
    </div> 
</template> 

<script> 
    import BasicCarousel from '@/components/BasicCarousel' 
    export default { 
    name: 'ToggleTile', 
    components: { 
     'basic-carousel': BasicCarousel, 
    }, 
    props: ['showtile'], 
    data() { 
     return { 
     showBlock: false, 
     images: [{ 
      image: '/static/img/meetings-slide.jpg', 
      active: true, 
      opacity: 1, 
      id: 1 
      }, 
      { 
      image: '/static/img/meetings-slide.jpg', 
      active: false, 
      opacity: 0, 
      id: 2 
      } 
     ], 
     } 
    }, 
    methods: { 
     toggleState: function() { 
     this.$emit('toggle-active'); 
     this.showBlock = this.showtile; 
     this.showBlock = true; 
     } 
    } 
    } 

</script> 

Merci

Répondre

0

C'est où brille Vue. Pour cela vous devez identifier vos tuiles afin que vous sachiez lequel est actif en ce moment. Quelque chose qui différencierait une tuile d'une autre.

La meilleure façon que je peux voir ce problème est. Au lieu d'avoir isActive: false en Explore il serait préférable d'avoir activeTile: 1 ou activeTile: 'FooTile' et un accessoire pour ToggleTile (id ou nom, de suivre cet exemple, mais pourrait être quelque chose)

Et dans votre composant ToggleTile émettent l'événement avec cette prop comme:

this.$emit('toggle-active', this.name) 
or 
this.$emit('toggle-active', this.id) 

Retour à Explore changer la fonction toggleTile

toggleTile: function (nameOrId) { 
    this.activeTile = nameOrId 
} 


<toggle-tile @toggle-active="toggleTile" :showtile="activeTile === 'FooTile'"></toggle-tile> 

<toggle-tile @toggle-active="toggleTile" :showtile="activeTile === 1"></toggle-tile> 

La "magie" ici est que chaque fois que activeTile changera ce prop showTile changera en montrant la tuile active et en cachant les autres.

Il s'agit d'une façon de penser courante lors du développement dans Vue. Dites quand cette condition sera vraie au lieu de faire les changements en cliquant ou quelque chose comme avec JQuery.