Добавление в сразу же двух классов

У меня есть две кнопки , одна меняет положение блока , вторая должна менять цвет блока , то есть когда я нажимаю на первую кнопку работает только изменение расположения блока , а когда я нажимаю на изменение цвета , оно не работает , я проверил , убрал первую кнопку с изменением расположения и оставил только изменение цвета и все работает и не могу понять , как сделать так ,чтобы работала и та и та кнопка ?

new Vue({
  el: '#app',
  data() {
    return {
      currentElement: 0,
      value: null,
      fadeOut: null,
      runProgress: null,
      animate: false,
      firstItem: [{
          class: 'top-left',
        },
        {
          class: 'top-center',
        },
        {
          class: 'top-right',
        },
        {
          class: 'midle-left',
        },
        {
          class: 'midle-center',
        },
        {
          class: 'midle-right',
        },
        {
          class: 'footer-left',
        },
        {
          class: 'footer-center',
        },
        {
          class: 'footer-right',
        },
      ],
      color: 0,
      changColor: [{
          class: 'green-color',
        },
        {
          class: 'grey-color'
        },
        {
          class: 'orange-color'
        },
        {
          class: 'red-color'
        },
      ]
    }
  },
  methods: {
    setElement() {
      this.currentElement += 1
    },
    changeCollors() {
      this.color += 1
    },
    changeFadeOut: function () {
      this.fadeOut = `fadeOut ${this.value}s linear forwards`
      this.runProgress = `runProgress ${this.value}s linear forwards`
      this.animate = true
    },
    onAnimationEnd: function(){
      this.animate = false
    }
  }
});
@import url(https://fonts.googleapis.com/css?family=Montserrat:100,200,300,regular,500,600,700,800,900);
.first-item {
    display: flex;
    align-items: center;
    height: 9.556vh;
    width: 38.542vw;
    opacity: 0.7;
    filter: drop-shadow(0px 6px 8px rgba(0, 0, 0, 0.25));
    background: linear-gradient(90.49deg, #007EFF 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
    box-shadow: 0px 4px 32px 3px rgba(0, 0, 0, 0.25);
    backdrop-filter: blur(1.389vh);
    border-radius: 2.389vh;
    overflow: hidden; 
    position: relative; 
}
 
.first-item__img {
    float: left;
    height: 5.556vh;
    width: 5.556vh; 
    padding: 1.189vh 1.389vh 0 1.389vh;
}
 
.first-item__text {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400;
    font-size: 2.03704vh;
    line-height: 1.3;
    display: flex;
    align-items: center;
    letter-spacing: -0.05em;
    color: #FFFFFF;
    text-shadow: 0px 0.4px 4px rgba(0, 0, 0, 0.5);
    padding-top: 2.189vh;
    margin-top: 0;
}
 
.first-item__progress {
    position: absolute;
    bottom: 0px;
    width: 0%;
    border-bottom: 0.512vh solid #FFFFFF;;
}
 
.first-item .first-item__progress {
    -webkit-animation: runProgress linear forwards;
    -moz-animation: runProgress linear forwards;
    -o-animation: runProgress linear forwards;
    -ms-animation: runProgress linear forwards;
    animation: runProgress linear forwards;
}
 
@-webkit-keyframes fadeOut {
    0% { opacity: 0; }
    10% { opacity: 1; }
    90% { opacity: 1; -webkit-transform: translateY(0px);}
    100% { opacity: 0; -webkit-transform: translateY(-25px);}
}
 
@-webkit-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@-moz-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@-o-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@-ms-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}

.top-left {
    position: absolute;
    top: 100px;
    left: 10px;
}
 
.top-center {
    position: absolute;
    top: 100px;
    left: calc(50% - 38.542vw / 2);
}

.top-right {
    position: absolute;
    top: 100px;
    left: calc(106% - 38.542vw);
}

.midle-left {
    position: absolute;
    top: calc(50% - 9.556vh);
}

.midle-center {
    position: absolute;
    top: calc(50% - 9.556vh);
    left: calc(50% - 38.542vw / 2);
}

.midle-right {
    position: absolute;
    top: calc(50% - 9.556vh);
    left: calc(106% - 38.542vw);
}

.footer-left {
    position: absolute;
    top: calc(98% - 9.556vh);
}

.footer-center {
    position: absolute;
    top: calc(98% - 9.556vh);
    left: calc(50% - 38.542vw / 2);
}

.footer-right {
    position: absolute;
    top: calc(98% - 9.556vh);
    left: calc(106% - 38.542vw);
}

.green-color {
    background: linear-gradient(90.49deg, #6FDE00 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}

.grey-color {
    background: linear-gradient(90.49deg, #BBBBBB 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}

.orange-color {
    background: linear-gradient(90.49deg, #FF6B00 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}

.red-color {
    background: linear-gradient(90.49deg, #FF0000 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
   <div id="app" class="wraper">
      <button @click="setElement">Change position</button>
      <input v-model="value">
      <button v-on:click="changeFadeOut">Time</button>
      <button @click="changeCollors">Color</button>
      <transition name="notify">
        <section class="first-item" :class="firstItem[currentElement].class" :class="changColor[color].class" v-if='animate' v-bind:style="{ animation: fadeOut }"  v-on:animationend="onAnimationEnd">
         <!--<section class="first-item" :class="firstItem[8].class">-->
          <img class="first-item__img" src="img/infocircle.png" alt="infocircle">
          <p class="first-item__text">Текстовый текст, что б его! Текстовый текст, что б его! <br> Текстовый текст, что б его! Текстовый текст, что б его!</p>
          <div class="first-item__progress" v-if='animate' v-bind:style="{ animation: runProgress }"  v-on:animationend="onAnimationEnd"></div>
        </section>
      </transition>
    </div>


Ответы (1 шт):

Автор решения: 4500zenja

Для передачи нескольких классов одновременно можно передать их параметру v-bind:class через массив — так они передадутся вместе, и проблема будет решена.

Ещё я поставил задержку для таймера на 1 секунду, потому что в процессе решения было оч неудобно смотреть, как плашка появляется и тут же исчезает >.< Она, кстати, делается через setTimeout(), вещь довольно полезная, особенно при тестировании :)

new Vue({
  el: '#app',
  data() {
    return {
      currentElement: 0,
      value: null,
      fadeOut: null,
      runProgress: null,
      animate: false,
      firstItem: [{
          class: 'top-left',
        },
        {
          class: 'top-center',
        },
        {
          class: 'top-right',
        },
        {
          class: 'midle-left',
        },
        {
          class: 'midle-center',
        },
        {
          class: 'midle-right',
        },
        {
          class: 'footer-left',
        },
        {
          class: 'footer-center',
        },
        {
          class: 'footer-right',
        },
      ],
      color: 0,
      changColor: [{
          class: 'green-color',
        },
        {
          class: 'grey-color'
        },
        {
          class: 'orange-color'
        },
        {
          class: 'red-color'
        },
      ]
    }
  },
  methods: {
    setElement() {
      this.currentElement += 1
    },
    changeCollors() {
      this.color += 1
    },
    changeFadeOut: function () {
      this.fadeOut = `fadeOut ${this.value}s linear forwards`
      this.runProgress = `runProgress ${this.value}s linear forwards`
      this.animate = true
    },
    onAnimationEnd: function(){
      setTimeout(() => this.animate = false, 1000);
    }
  }
});
@import url(https://fonts.googleapis.com/css?family=Montserrat:100,200,300,regular,500,600,700,800,900);
.first-item {
    display: flex;
    align-items: center;
    height: 9.556vh;
    width: 38.542vw;
    opacity: 0.7;
    filter: drop-shadow(0px 6px 8px rgba(0, 0, 0, 0.25));
    background: linear-gradient(90.49deg, #007EFF 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
    box-shadow: 0px 4px 32px 3px rgba(0, 0, 0, 0.25);
    backdrop-filter: blur(1.389vh);
    border-radius: 2.389vh;
    overflow: hidden; 
    position: relative; 
}
 
.first-item__img {
    float: left;
    height: 5.556vh;
    width: 5.556vh; 
    padding: 1.189vh 1.389vh 0 1.389vh;
}
 
.first-item__text {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400;
    font-size: 2.03704vh;
    line-height: 1.3;
    display: flex;
    align-items: center;
    letter-spacing: -0.05em;
    color: #FFFFFF;
    text-shadow: 0px 0.4px 4px rgba(0, 0, 0, 0.5);
    padding-top: 2.189vh;
    margin-top: 0;
}
 
.first-item__progress {
    position: absolute;
    bottom: 0px;
    width: 0%;
    border-bottom: 0.512vh solid #FFFFFF;;
}
 
.first-item .first-item__progress {
    -webkit-animation: runProgress linear forwards;
    -moz-animation: runProgress linear forwards;
    -o-animation: runProgress linear forwards;
    -ms-animation: runProgress linear forwards;
    animation: runProgress linear forwards;
}
 
@-webkit-keyframes fadeOut {
    0% { opacity: 0; }
    10% { opacity: 1; }
    90% { opacity: 1; -webkit-transform: translateY(0px);}
    100% { opacity: 0; -webkit-transform: translateY(-25px);}
}
 
@-webkit-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@-moz-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@-o-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@-ms-keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}
 
@keyframes runProgress {
    0%{ width: 0%; }
    100%{ width: 100%; }
}

.top-left {
    position: absolute;
    top: 100px;
    left: 10px;
}
 
.top-center {
    position: absolute;
    top: 100px;
    left: calc(50% - 38.542vw / 2);
}

.top-right {
    position: absolute;
    top: 100px;
    left: calc(106% - 38.542vw);
}

.midle-left {
    position: absolute;
    top: calc(50% - 9.556vh);
}

.midle-center {
    position: absolute;
    top: calc(50% - 9.556vh);
    left: calc(50% - 38.542vw / 2);
}

.midle-right {
    position: absolute;
    top: calc(50% - 9.556vh);
    left: calc(106% - 38.542vw);
}

.footer-left {
    position: absolute;
    top: calc(98% - 9.556vh);
}

.footer-center {
    position: absolute;
    top: calc(98% - 9.556vh);
    left: calc(50% - 38.542vw / 2);
}

.footer-right {
    position: absolute;
    top: calc(98% - 9.556vh);
    left: calc(106% - 38.542vw);
}

.green-color {
    background: linear-gradient(90.49deg, #6FDE00 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}

.grey-color {
    background: linear-gradient(90.49deg, #BBBBBB 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}

.orange-color {
    background: linear-gradient(90.49deg, #FF6B00 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}

.red-color {
    background: linear-gradient(90.49deg, #FF0000 0.42%, rgba(0, 0, 0, 0.6) 95.58%);
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
   <div id="app" class="wraper">
      <button @click="setElement">Change position</button>
      <input v-model="value">
      <button v-on:click="changeFadeOut">Time</button>
      <button @click="changeCollors">Color</button>
      <transition name="notify">
        <section class="first-item" :class="[firstItem[currentElement].class, changColor[color].class]" v-if='animate' v-bind:style="{ animation: fadeOut }"  v-on:animationend="onAnimationEnd">
         <!--<section class="first-item" :class="firstItem[8].class">-->
          <img class="first-item__img" src="img/infocircle.png" alt="infocircle">
          <p class="first-item__text">Текстовый текст, что б его! Текстовый текст, что б его! <br> Текстовый текст, что б его! Текстовый текст, что б его!</p>
          <div class="first-item__progress" v-if='animate' v-bind:style="{ animation: runProgress }"  v-on:animationend="onAnimationEnd"></div>
        </section>
      </transition>
    </div>

→ Ссылка