Добавить цвет фона при изменении данных с Vue - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть 3 контейнера, первые два из которых имеют функцию перетаскивания, поэтому, когда я помещаю туда элемент, он меняет цвет этого контейнера. Это работает правильно, но я хочу, чтобы, когда у 1-го и 2-го контейнера был цвет, 3-й автоматически обновляется до нового цвета. Я использую Vuejs.

Например: контейнер 1 имеет красный цвет, а контейнер 2 - желтый. Третий контейнер автоматически обновится до оранжевого цвета. Это будет происходить каждый раз, когда я меняю цвет контейнеров.

Это мой код:

HTML

 <!-- the containers where I drop the elements --> 
          <div class="box-flex">
              <div class="box" @dragover.prevent @drop="drop" id="box-1"></div>
              <div class="box" @dragover.prevent @drop="drop2" id="box-2"></div>
              <div class="box" id="box-3"></div>
          </div>
      <!-- the elements I want to drag -->
      <div v-for="(flower, i) in flowers" :key="i">
          <div v-if="flower_type == flower.type">
            <p>{{ flower.type }}</p>

            <p v-for="(color, j) in flower.colors" :key="j">
              <span
                :id="flower.type + '-' + color"
                :draggable="true"
                @dragstart="dragStart"
                @dragover.stop
              >{{ color }}</span>
            </p>
          </div>
        </div>

СКРИПТ

 data() {
        return {
          //flowers
          flowers: [
            {
              type: "Cosmos",
              colors: ["red", "yellow", "orange", "black", "pink", "white"]
            },
          ],
        };
      },

      methods: {
        dragStart(e) {
          let target = e.target;
          e.dataTransfer.setData("color_id", target.id);
          e.dataTransfer.setData("box_el", target);
          let box1 = document.getElementById("box-1");
        },
        //first container drop
        drop(e) {
          let colorId = e.dataTransfer.getData("color_id"); //id of the color (red, yellow...)
          let colorEl = e.dataTransfer.getData("box_el"); //element of the color
          let box1 = document.getElementById("box-1");

          box1.classList.add(colorId);

          if (box1.classList.length > 2) { //I only want one color-class in the container
            box1.classList.remove(box1.classList[1]);
          }
        },
        //second container drop
        drop2(e) {
          let colorId = e.dataTransfer.getData("color_id"); //id of the color (red, yellow...)
          let colorEl = e.dataTransfer.getData("box_el"); //element of the color
          let box2 = document.getElementById("box-2");

          box2.classList.add(colorId);
          if (box2.classList.length > 2) {
            box2.classList.remove(box2.classList[1]);
          }
        }
      },
      computed: {
        evFlower() {
          let box1 = document.getElementById("box-1");
          let box2 = document.getElementById("box-2");
          let box3 = document.getElementById("box-3");
          if (
            box1.classList.contains("Cosmos-red") &&
            box2.classList.contains("Cosmos-yellow")
          ) {
              box3.classList.add("Cosmos-orange");
          }
        }
      }

CSS

.box-flex {
  height: 50%;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.box,
.box-1,
.box-2 {
  width: 20%;
  height: 20%;
  border: 2px solid black;
}
.Cosmos-red {
  background: red;
}

.Cosmos-yellow {
  background: yellow;
}

.Cosmos-orange {
  background: orange;
}

Я пытался с наблюдателем, но не нашел способ «следить» за изменениями DOM.

Заранее спасибо !!

1 Ответ

0 голосов
/ 26 апреля 2020

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

Это лучшее решение для добавления встроенных стилей или переключения классов в шаблонах vue с помощью реактивные данные вместо добавления и удаления классов непосредственно в DOM, как это было бы со старыми Jquery.

. Это реактивные, простые и дешевые средства управления:

 <div :style="{ background: box1}"></div>

I переписал ваш код в соответствии с этими правилами:

<template>
  <div>
  <div class="box-flex">
      <div class="box" @dragover.prevent @drop="drop" id="box-1" :style="{ background: box1}"></div>
      <div class="box" @dragover.prevent @drop="drop2" id="box-2" :style="{ background: box2}"></div>
      <div class="box" :style="{ background: box3}"></div>
  </div>
<!-- the elements I want to drag -->
<div v-for="(flower, i) in flowers" :key="i">
  <div>
    <p>{{ flower.type }}</p>

    <p v-for="(color, j) in flower.colors" :key="j">
      <span
        :id="color"
        :draggable="true"
        @dragstart="dragStart"
        @dragover.stop
      >{{ color }}</span>
    </p>
  </div>
</div>
</div>
</template>
<script>

export default {

  name: 'Intro',

  components: {
  },

  data() {
    return {
      //flowers
      flowers: [
        {
          type: "Cosmos",
          colors: ["red", "yellow", "orange", "black", "pink", "white"]
        },
      ],
      box1: 'white',
      box2: 'white',
      box3: 'white',
    };
  },

  methods: {
    dragStart(e) {
      let target = e.target;
      e.dataTransfer.setData("color_id", target.id);
      e.dataTransfer.setData("box_el", target);
    },
    //first container drop
    drop(e) {
      this.box1 = e.dataTransfer.getData("color_id");
      if ( this.box1 == 'red' && this.box2 == 'yellow') {
        this.box3 = 'orange'
      }
      else {
        this.box3 = 'white'
      }
    },
    //second container drop
    drop2(e) {
      this.box2 = e.dataTransfer.getData("color_id");
      if ( this.box1 == 'red' && this.box2 == 'yellow') {
        this.box3 = 'orange'
      }
      else {
        this.box3 = 'white'
      }
    }
  },
};
</script>
<style>
.box-flex {
  height: 50px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.box,
.box-1,
.box-2 {
  width: 20px;
  height: 20px;
  border: 2px solid black;
}
.Cosmos-red {
  background: red;
}

.Cosmos-yellow {
  background: yellow;
}

.Cosmos-orange {
  background: orange;
}
</style>
...