Использование миксина для двух компонентов: он вызывает метод только для первого компонента

У меня есть два компонента, которым нужен общий метод. Я использовал миксин для этого метода и добавил миксин к обоим компонентам. Когда я нажимаю на второй компонент, он запускает метод для первого компонента вместо второго - в этом случае он открывает верхний раскрывающийся список, а не второй раскрывающийся список.

Вот фрагмент моего кода ...

// Mixins

var showDropdownMixin = {
  data() {
    return {
      activeTrigger: false,
      dropdown: false
    }
  },
  methods: {
    showDropdown: function(){
      if(this.dropdown == false){
        this.dropdown = true;
        this.activeTrigger = true;
        TweenMax.fromTo(
          "#dropdown",
          0.55,
          {
            autoAlpha: 0,
            y: -10
          },
          {
            autoAlpha: 1,
            y: 0,
            ease: Power2.easeOut
          }
        );
      }else{
        this.dropdown = false;
        this.activeTrigger = false;
         TweenMax.to(
          "#dropdown",
          0.2,
          {
            autoAlpha: 0,
            y: -10,
            ease: Power2.easeOut
          });
      }

    }
  }
}








//Global Components

Vue.component('photo-questions', {
  data() {
    return {
      filters: [
        "Q2: Message: Vermont Village 8oz Sipping Vinegar products have had issues with…",
        "Q10: This is the second photo question.",
        "Q11: This is the third photo question.",
        "Q12: This is the fourth photo question.",
        "Q13: This is the fifth photo question.",
        "Q14: This is the sixth photo question.",
        "Q15: This is the seventh photo question.",
        "Q16: This is the eighth photo question.",
        "Q17: This is the ninth photo question.",
        "Q18: This is the tenth photo question.",
        "Q19: This is the eleventh photo question.",
        "Q20: This is the twelfth photo question."
      ],
      checkedFilters: [],
      allSelected: true,
      selectAllText: 'Select All'
    };
  },
  template: '#photo-questions-template',
  computed: {
    filteredList() {
      return this.filters.filter(item => {
        return item.toLowerCase();
      });
    }
  },
  methods: {
    selectAll: function() {
      this.checkedFilters = [];
      this.selectAllText = this.selectAllText == "Select All" ? 'Clear All' : 'Select All';
      if (this.allSelected) {
        for (filter in this.filters) {
          this.checkedFilters.push(this.filters[filter].toString());
        }
      }
    }
  },
  mixins: [showDropdownMixin]
})



Vue.component('associated-questions', {
  data() {
    return {
      filters: [
        "Q2: Message: Vermont Village 8oz Sipping Vinegar products have had issues with…",
        "Q10: This is the second photo question.",
        "Q11: This is the third photo question.",
        "Q12: This is the fourth photo question.",
        "Q13: This is the fifth photo question.",
        "Q14: This is the sixth photo question.",
        "Q15: This is the seventh photo question.",
        "Q16: This is the eighth photo question.",
        "Q17: This is the ninth photo question.",
        "Q18: This is the tenth photo question.",
        "Q19: This is the eleventh photo question.",
        "Q20: This is the twelfth photo question."
      ],
      checkedFilters: [],
      allSelected: true,
      selectAllText: 'Select All'
    };
  },
  template: '#associated-questions-template',
  computed: {
    filteredList() {
      return this.filters.filter(item => {
        return item.toLowerCase();
      });
    }
  },
  methods: {
    selectAll: function() {
      this.checkedFilters = [];
      this.selectAllText = this.selectAllText == "Select All" ? 'Clear All' : 'Select All';
      if (this.allSelected) {
        for (filter in this.filters) {
          this.checkedFilters.push(this.filters[filter].toString());
        }
      }
    }
  },
  mixins: [showDropdownMixin]
})





//Main Vue Instance

function run_app(){

    const searchFilters = new Vue({
        el: '#searchFilters',
        data: {
            title: "Vue is working"
        },
    });

};

window.addEventListener("load", function(event){
    run_app()
});
/**********************
     Global Styles
***********************/

body {

}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
}


*, :after, :before {
  box-sizing: border-box;
}


/**********************
     Tab/Container
***********************/

#active-tab {
    color: #fff;
    cursor: default;
    background-color: #2CACDF;
    border: 1px solid #2CACDF;
    border-bottom-color: transparent;
}

#active-tab:hover {
    color: #fff;
    cursor: pointer;
    background-color: #2CACDF;
    border: 1px solid #2CACDF;
}

.nav-tabs li a {
    font-size: 1.25rem;
    font-weight: bold;
}

.search-container {
    border: 1px solid #ddd;
    padding : 25px 15px;
}

.search-container select {
    width: 100%;
}





/**********************
     Search/Filters
***********************/

.search-container input {
    margin-right: 5rem;
}

.checkbox-select {
  position: relative;
  max-width: 800px;
  width: 100%;
  margin: 2rem 0;
}

.checkbox-select li {
    list-style: none;
}

.checkbox-select__trigger {
  border-radius: 2px;
  background: #fff;
  box-shadow: 3px 3px 12px 1px rgba(0, 0, 0, 0.2);
  height: 40px;
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 0 25px;
  transition: all 0.4s ease;
}

.checkbox-select__trigger.isActive svg {
  transform: rotate(-180deg);
}

.checkbox-select__trigger svg {
  width: 1rem;
  transition: all 0.4s ease;
}

.checkbox-select__title {
  font-size: 1.25rem;
  font-weight: bold;
  flex: 1;
  padding-right: 1rem;
}

.checkbox-select__dropdown {
  opacity: 0;
  visibility: hidden;
  background: #fff;
  position: absolute;
  left: 0;
  right: 0;
  box-shadow: 3px 3px 12px 1px rgba(0, 0, 0, 0.2);
  border-radius: 0;
  overflow: hidden;
  padding-bottom: 25px;
  z-index: 1000;
}

.checkbox-select__dropdown .simplebar-scrollbar {
  width: 3px;
  right: 1px;
}

.checkbox-select__col {
  display: flex;
  font-size: 1rem;
  padding: 25px 25px 0px 25px;
  justify-content: space-between;
  text-transform: uppercase;
}

.checkbox-select__select-all label {
  cursor: pointer;
}

.checkbox-select__select-all input {
  display: none;
}

.checkbox-select__filters-wrapp {
  margin-top: 20px;
  padding-left: 2.5rem;
  height: 150px;
  overflow-y: auto;
}

.checkbox-select__check-wrapp {
  position: relative;
  padding: 0;
  margin-bottom: 10px;
}

.checkbox-select__check-wrapp input[type="checkbox"] {
  display: none;
}

.checkbox-select__check-wrapp input[type="checkbox"] + label {
  position: relative;
  cursor: pointer;
  font-size: 1rem;
  line-height: 22px;
  padding-left: 30px;
  display: inline-block;
  transition: padding 0.25s ease;
}

.checkbox-select__check-wrapp input[type="checkbox"] + label:after {
  border: solid 1px #c7c7c7;
  border-radius: 3px;
  content: "";
  width: 18px;
  height: 18px;
  top: 0;
  left: 0;
  position: absolute;
}

.checkbox-select__check-wrapp input[type="checkbox"] + label:before {
  width: 10px;
  height: 10px;
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  background-color: #2cacdF;
  opacity: 0;
  will-change: transform;
  transform: scale(0.5);
  transition: all 0.2s ease;
}

.checkbox-select__check-wrapp input[type="checkbox"] + label:hover {
  padding-left: 32px;
}

.checkbox-select__check-wrapp input[type="checkbox"]:checked + label:before {
  opacity: 1;
  transform: scale(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-tabs">
            <li class="active"><a>Review Photos</a></li>
            <li><a href="#" id="active-tab">Mass Approvals Page</a></li>
        </ul>

        <div id="searchFilters" class="search-container container-fluid">

            <div class="col-md-12">

                <label for="project-id">Project ID:</label>
                <input type="text" id="project-id" name="project-id">

                <label for="job-id">Job ID:</label>
                <input type="text" id="job-id" name="job-id">

                <label for="all-photo-questions">All Photo Questions:</label>
                <input type="checkbox" id="all-photo-questions" name="all-photo-questions">

                <button>Reset Filters</button>
            </div>

            <div class="col-md-6">
                <photo-questions></photo-questions>
                <associated-questions></associated-questions>
            </div>

            <div class="col-md-6">

            </div>

        </div>




        <!-- Component Templates -->

        <script type="text/x-template" id="photo-questions-template">
            <div class="checkbox-select">
                <div class="checkbox-select__trigger" :class="{ isActive: activeTrigger }" @click="showDropdown()">
                    <span class="checkbox-select__title">Photo Questions:</span>
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129 129"><path d="M121.3 34.6c-1.6-1.6-4.2-1.6-5.8 0l-51 51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8 0-1.6 1.6-1.6 4.2 0 5.8l53.9 53.9c.8.8 1.8 1.2 2.9 1.2 1 0 2.1-.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2.1-5.8z"/></svg>
                </div>
                <div id="dropdown" class="checkbox-select__dropdown">
                    <div class="checkbox-select__col">
                        <div class="checkbox-select__select-all">
                            <label for="selectAll">{{selectAllText}}</label>
                            <input type="checkbox" id="selectAll" @click="selectAll" v-model="allSelected">
                        </div>
                        <div class="checkbox-select__info">
                            {{checkedFilters.length}} SELECTED
                        </div>
                    </div>
                    <ul id="customScroll" class="checkbox-select__filters-wrapp" data-simplebar-auto-hide="false">
                        <li v-for="(filter, index) in filteredList">
                              <div class="checkbox-select__check-wrapp">
                                  <input :id="index" class="conditions-check" v-model="checkedFilters" :value="filter" type="checkbox">
                                  <label :for="index">{{filter}}</label>
                              </div>
                        </li>
                    </ul>
                </div>
            </div>
        </script>





        <script type="text/x-template" id="associated-questions-template">
            <div class="checkbox-select">
                <div class="checkbox-select__trigger" :class="{ isActive: activeTrigger }" @click="showDropdown()">
                    <span class="checkbox-select__title">Associated Questions:</span>
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129 129"><path d="M121.3 34.6c-1.6-1.6-4.2-1.6-5.8 0l-51 51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8 0-1.6 1.6-1.6 4.2 0 5.8l53.9 53.9c.8.8 1.8 1.2 2.9 1.2 1 0 2.1-.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2.1-5.8z"/></svg>
                </div>
                <div id="dropdown" class="checkbox-select__dropdown">
                    <div class="checkbox-select__col">
                        <div class="checkbox-select__select-all">
                            <label for="selectAll">{{selectAllText}}</label>
                            <input type="checkbox" id="selectAll" @click="selectAll" v-model="allSelected">
                        </div>
                        <div class="checkbox-select__info">
                            {{checkedFilters.length}} SELECTED
                        </div>
                    </div>
                    <ul id="customScroll" class="checkbox-select__filters-wrapp" data-simplebar-auto-hide="false">
                        <li v-for="(filter, index) in filteredList">
                              <div class="checkbox-select__check-wrapp">
                                  <input :id="index" class="conditions-check" v-model="checkedFilters" :value="filter" type="checkbox">
                                  <label :for="index">{{filter}}</label>
                              </div>
                        </li>
                    </ul>
                </div>
            </div>
        </script>


person AndrewTheGeek    schedule 16.11.2018    source источник


Ответы (1)


У вас есть два элемента с одинаковым идентификатором: dropdown. Похоже, что TweenMax запрашивает созданную страницу, чтобы найти, где прикрепить меню, и просто переходит к первой найденной странице.

Вы можете сделать идентификатор для каждого элемента уникальным и передать его в качестве параметра в свой метод showDropdown.

person Joe Z    schedule 16.11.2018