Estoy tratando de cambiar el color de un div cuando se hace clic en él.
esta es la estructura del div
<li v-for="monomer in monomers"> <div :style="monomerButton" @mouseover="hover = true" @mouseleave="hover = false" @click="selectMonomer($event)" class="monomer-button"> <p class="monomer-symbol">{{monomer.symbol}}</p> </div> </li>esta es la función que se llama cuando se llama al evento onclick
selectMonomer(event) { // If the p element gets clicked, get the div that contains the p element let element = event.target.nodeName === "P" ? event.target.parentElement : event.target element.style.backgroundColor = "rgba(44, 224, 203, 0.5)" }El color cambia y permanece así mientras mantengo el mouse sobre el div. Sin embargo, cuando el mouse abandona el div, el color vuelve a su color original. Al hacer clic en él nuevamente, se cambiará nuevamente, pero se revertirá cuando el mouse se vaya nuevamente.
¿Cómo consigo que el div mantenga el color?
Editar:
monomerButton: { backgroundColor: getNodeColor(this.monomers[0].polymerType, this.monomers[0].naturalAnalog) }El color de fondo depende del tipo de monómero que sea.
Edit2: todo el componente (llamémoslo componente A) está en un bucle for anidado dentro de un componente diferente (componente B). el componente B se parece a esto:
<component B> <ul> <li v-for="monomer type in monomer types"> <component A :monomers="monomers of that type"></component A> </li> <ul> </component B> entonces, para cada tipo de monómero, como Glicina + análogos de glicina, cisteína + análogos de cisteína, se crea un componente. Este componente (componente A) crea un pequeño div cuadrado con texto para cada análogo. Esta es la razón por la que getNodeColor(this.monomers[0].polymerType, this.monomers[0].naturalAnalog) puede simplemente tomar el primer elemento porque todos los divs en una sola instancia del componente A deben tener el mismo color.
Entonces, gracias a @Shoejep, descubrí una respuesta.
// component A mounted() { this.monomers.forEach(monomer => { monomer.selected = false }) }En el gancho montado le di a cada monómero un atributo 'seleccionado'. Por supuesto, todos comienzan como no seleccionados.
// component A <div :style="monomerButton(monomer)" @mouseover="hover = true" @mouseleave="hover = false" @click="selectMonomer(monomer)" class="monomer-button"> <p class="monomer-symbol">{{monomer.symbol}}</p> </div> Hice que el atributo :style use el valor de retorno de getMonomerStyle() que se define como:
// component A getMonomerStyle(monomer) { return { backgroundColor: monomer.selected ? "rgba(131, 222, 226, 0.8)" : getNodeColor(this.monomers[0].polymerType, this.monomers[0].naturalAnalog), border: this.monomers[0].monomerType === "Terminal" ? "2px dashed" : "1px solid" } }Cuando se hace clic en un mononer, ese monómero se emite al componente principal. Esto es para que todas las demás instancias del componente A también sepan qué monómero se selecciona.
entonces es simplemente establecer el atributo seleccionado en verdadero para el monómero seleccionado y establecer el atributo seleccionado en falso para el monómero previamente seleccionado.
if (this.previousSelected) { this.previousSelected.selected = false } monomer.selected = true this.previousSelected = monomerPodría hacer algo como el fragmento que he incluido a continuación.
Tenga una propiedad selected en cada monómero, luego, cuando calcule el estilo que debería estar en div, calcule en función de si ese monómero está seleccionado o no.
Esto también simplificará parte del código que presentaste, porque si haces clic en el elemento p , aparecerá hasta el div y establecerá el monómero como seleccionado.
Vue.config.devtools = false; Vue.config.productionTip = false; new Vue({ el: "#app", data: { monomers: [{ polymerType: "Test", naturalAnalog: "Test", symbol: "Test", selected: false }, { polymerType: "Hello", naturalAnalog: "Hello", symbol: "Hello", selected: false }, { polymerType: "World", naturalAnalog: "World", symbol: "World", selected: false } ], hover: true }, methods: { getNodeColor: function(polymerType, naturalAnalog) { return "lightblue"; }, selectMonomer: function(monomer) { monomer.selected = !monomer.selected; }, monomerButton: function(monomer) { return `backgroundColor: ${monomer.selected ? "pink" : this.getNodeColor(monomer.polymerType, monomer.naturalAnalog)}`; } } }); ul { list-style: none; padding: 0; margin: 0; } li div { padding: 8px; } li { margin-bottom: 5px; } <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <ul> <li v-for="monomer in monomers"> <div :style="monomerButton(monomer)" @mouseover="hover = true" @mouseleave="hover = false" @click="selectMonomer(monomer)" class="monomer-button"> <p class="monomer-symbol">{{monomer.symbol}}</p> </div> </li> </ul> </div>