使用 Vue 更改数据时添加背景颜色
Add background color when data changes with Vue
我有 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;
}
我试过观察者,但没有找到 'watch' 对 DOM 更改的方法。
提前致谢!!
我认为你把事情复杂化了,最好避免 DOM 操作,除非确实需要。
更好的解决方案是添加内联样式,或者在具有反应性数据的 vue 模板上切换 类 而不是直接在 DOM 上添加和删除 类 d 处理旧的 Jquery.
这是反应性的,易于控制且成本低廉:
<div :style="{ background: box1}"></div>
我已经按照以下规则重写了您的代码:
<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>
我有 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;
}
我试过观察者,但没有找到 'watch' 对 DOM 更改的方法。
提前致谢!!
我认为你把事情复杂化了,最好避免 DOM 操作,除非确实需要。
更好的解决方案是添加内联样式,或者在具有反应性数据的 vue 模板上切换 类 而不是直接在 DOM 上添加和删除 类 d 处理旧的 Jquery.
这是反应性的,易于控制且成本低廉:
<div :style="{ background: box1}"></div>
我已经按照以下规则重写了您的代码:
<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>