No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Estilos reactivos

12/23
Recursos

Aportes 30

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Los estilos utilizados:

<style>
        html, body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        #app, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }
        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }
        .closed {
            background-color: #eca1a6;
        }
        .open {
            background-color: #b5e7a0;
        }
    </style>

Al usar ReactJs se me esta haciendo mas fá
cil entender el funcionamiento básico de VueJs. El objeto data es parecido al hook useState, la propiedad watch a useEffect.

Otra manera de hacerlo sería crear un método dentro de methods obviamente, al cual podríamos llamar toggleDoor(), en el cual ponemos la lógica de “this.open = !this.open”, y tras esto, escribir la lógica de los estilos css:

const vm = Vue.createApp({
            data(){
                return {
                    text: "Puerta cerrada",
                    open: false,
                    styles: {
                        backgroundColor: "#eca1a6",
                    },
                };

               
            },

            methods: {

                toggleDoor(){
                    this.open = !this.open;

                    this.open ? this.styles.backgroundColor = "#b5e7a0" : this.styles.backgroundColor = "#eca1a6"
                }

            },

            watch: {
                open(value){
                    if (value){
                        this.text = "Puerta abierta";
                    }
                    else{
                        this.text = "Puerta cerrada";
                        
                    }
                }
            },

            template: `
                <div class="container" :style="styles">
                    <h2>{{text}}</h2>
                    <button @click="toggleDoor">{{open ? "Cerrar" : "Abrir"}}</button> 
                </div>
                
            `
        }).mount("#app");

Además de la falicidad que da vue para manejar estilos entre otras cosas. sigo aprendiendo de esos errores de novatos!! que hayan más errores para saber como resolverlos en el futuro.

Todo esto me recuerda al curso de WebComponents… aunque aqui en vue es mucho mas facil, hasta ahora :3

Maravilloso.
Finalmente siento que me están entrando los conceptos básicos de Vue.

Gracias 😃

Una necesidad común de data binding es manipular la lista de clases de un elemento y sus estilos en línea. Como ambos son atributos, podemos usar v-bind para manejarlos: solo necesitamos crear una cadena de texto con nuestras expresiones. Sin embargo, concatenar cadenas de texto puede llegar a ser incómodo y propenso a errores. Por esta razón, Vue proporciona mejoras cuando se utiliza v-bind conclass y style. Además de las cadenas de texto, las expresiones también pueden evaluar objetos o matrices.

fuente:
https://es.vuejs.org/v2/guide/class-and-style.html

Es la documentacion de Vue en español

Creo que Vue es increible, yo he trabajado con React y la verdad me fue un poco dificil entender la reactividad al principio, pero con Vue es super facil de comprender.

Como creo que todos estan haciendo el reto de ponerle una imagen al codigo, quise intentarlo y este fue mi codigo (Aunque reutilice los estilos de la clase)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="https://unpkg.com/vue@next"></script>
    <main id="app"></main>

    <script>
        const vue = Vue.createApp({
            data() {
                return {
                    text: "La puerta esta cerrada",
                    isOpen: false,
                }
            },
            watch: {
                isOpen(current) {
                    if(current) {
                        this.text = "La puerta esta abierta"
                    } else {
                        this.text = "La puerta esta cerrada"
                    }
                }
            },
            computed: {
                image() {
                    return this.isOpen ? "https://us.123rf.com/450wm/grebeshkovmaxim/grebeshkovmaxim1904/grebeshkovmaxim190400553/123026095-abrir-puerta-realista-aislada-en-sala-blanca.jpg?ver=6" : "https://previews.123rf.com/images/byzonda/byzonda1505/byzonda150500089/40505435-blanc-porte-ferm%C3%A9e-avec-cadre.jpg";
                },
                
                bgColor() {
                    return this.isOpen ? 'open' : 'closed';
                },
                
                label() {
                    return this.isOpen ? 'Close' : 'Open'
                }
            },
            methods: {
                changeOpen() {
                    return this.isOpen = !this.isOpen
                }
            },
            template: `
            <div class="container" :class="bgColor">
                <h2>{{text}}</h2>
                <img :src="image"/>
                <button type="button" @click="changeOpen">{{ label }}</button>
            </div>
            `
        }).mount('#app');
    </script>
    
    <style>
        html, body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        #app, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }

        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }

        img {
            height: 400px;
            width: 400px;
            border-radius: 12px;
        }

        .open {
            background-color: rgb(100, 226, 100);
        }

        .closed {
            background-color: rgb(219, 102, 102);
        }
    </style>
</body>
</html>

Siendo honesto, las clases me han parecido una maravilla. Estoy entiendo super bien todos los conceptos, pero creo que tengo algo de ventaja por venir de React y de Angular. Vue.js con las directivas y el data binding es muy parecido a lo que tiene Angular. Aparte de tiene su parecido a los hooks de React con el data, funcionando con el useState, y el watch al useEffect, useMemo y así. Aunque creo que aun sin tener este contexto podría entenderle a la maestra, ya que sus ejemplos son super claros y muestra las distintas formas de como hacer destinas cosas. Esto se aprecia mucho y se que iré adquiriendo y adhiriendo estos conceptos y forma de desarrollar a medida que adquiera mas practica.

antes de seguir avanzando te recomiendo este articulo
https://codingpotions.com/atributos-clases-estilos-dinamicos-vuejs

Hasta el momento me ha parecido muy bueno el curso, la explicación es excelente

Hola, vi un ejemplo e intente realizarlo yo mismo, aqui unas fotos y el codigo!

<style>
        html, body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        #app, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }
        img {
            width: 200px;
        }
        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }
        .closed {
            background-color: #eca1a6;
        }
        .open {
            background-color: #b5e7a0;
        }
    </style>

<div id="app"></div>
<script>
    const vm = Vue.createApp({
        data() {
            return {
                text: "Puerta cerrada",
                open: false,
                img: "close.png"
            };
        },
        watch: {
            open(value) {
                if (value) {
                    this.img = "open.png";
                    this.text = "Puerta abierta";
                } else {
                    this.img = "close.png";
                    this.text = "Puerta cerrada";
                }
            }
        },
        computed: {
            label() {
                return this.open ? "Cerrar" : "Abrir";
            },
            styles() {
                return this.open ? 'open' : 'closed';
            }
        },
        template: `
            <div class="container" :class="styles">
                <h2>{{ text }}</h2>
                <img :src="img">
                <button @click="open = !open">{{ label }}</button>
            </div>
        `
    }).mount("#app");
</script>

En mi caso use JQuery para añadir y remover las clases correspondientes, puse por defecto la clase closed y ya luego añadía y removía la correspondiente, el método container_styles_2 lo llamo luego del método que cambia el valor de open y me sirve correctamente

const vm = Vue.createApp({
            data: () => {
                return {

                    text: "Puerta Cerrada",
                    open: false,
                };
            },
            computed: {
                action: function () {

                    return this.open ? "Cerrar" : "Abrir";
                },
                container_styles: function() {
                    return this.open ? ['open'] : ['closed'];
                }
            },
            watch: {
                open: function(value) {

                    this.text = value ? "Puerta Abierta" : "Puerta Cerrada";
                }
            },
            methods: {
                door: function () {

                    this.open = !this.open;
                    this.container_styles_2();
                },
                container_styles_2: function() {

                    if (this.open) {
                        
                        $("#app .container").removeClass("closed");
                        $("#app .container").addClass("open");
                    } else {
                        
                        $("#app .container").removeClass("open");
                        $("#app .container").addClass("closed");
                    }
                }
            },
            template: 
            ` 
            <div class="container closed">
                <h2>{{ text }}</h2>
                <button v-on:click="door">{{ action }}</button>
            </div>
            `   
        }).mount("#app");

muy buena clase

VAle con diana estoy entendiedo Vue bien facil

les comparto el codigo con la hoja de estilos por separado

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="open_close_door.css">
    <title>Document</title>
</head>
<body>
    <script src="https://unpkg.com/vue@3"></script>

    <div id="app"></div>
    
    <script>
        const vm = Vue.createApp( {
            data() {
                return {
                    text: "Hey you!",
                    open: false,
                };
            },
            watch:{
                open(value){
                    if (value){
                        this.text= "La puerta está abierta, Pasa!";
                    }else {
                        this.text= "La puerta está cerrada, Lo siento!";
                    }
                }
            },
         
            computed:{
                label(){
                    return this.open ? "Cerrar" : "Abrir";
                },

                //con la función computada para los estilos usamos las clases
                styles(){
                    return this.open ? [`open`] : [`close`];
                }
                
            },
            
            template: `
                <div class="container" :class="styles">
                    <h1>{{ text }}</h1>
                    <button @click="open = !open">{{ label }}</button>
                </div>
            `
        }).mount("#app");
    </script>
</body>
</html>
*{
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html{
    font-size: 62.5%;
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
}

#app .container{
    display: flex;
    align-content: center;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    width: 100%;
    height: 700px;
    padding: 2rem;
    
}

h1{
    margin-top: 2rem;
    margin-bottom: 2rem;
    font-size: 40px;

}

button{
    width: 80px;
    height: 25px;
    border-radius: 1rem;
    color: white;
    font-weight: bold;
    background-color: black;
}

button:hover{
    background-color: rgb(255, 246, 146);
    color: black;
    font-weight: bold;
}

.close{
    background-color: rgb(156, 63, 63) ;
}

.open{
    background-color: rgb(90, 168, 90);
}

Mi aporte 2 ejemplos de la clase

<div class="container" :style="styles">
            <h2>{{message}}</h2>
            <button @click = 'open =! open'>{{label}}</button>
        </div>
        <div class="container" :class="openDoor">
            <h2>{{message}}</h2>
            <button @click = 'open =! open'>{{label}}</button>
        </div>
 data() {
                return {
                    open: false,
                    styles: {
                        backgroundColor: '#eca1a6'
                    }
                }
            },
watch: {
                open(value){
                    if(value){
                        this.message = 'Puerta  abierta';
                        this.styles.backgroundColor = '#b5e7a0'
                    }else{
                        this.message = 'Puerta  cerrada';
                        this.styles.backgroundColor='#eca1a6'
                    }
                }
            }

            computed: {
                label(){
                    return this.open ? 'cerrar' : 'Abrir'
                },
                openDoor(){
                    return this.open ? ['open'] : ['closed'];
                }
\<script src="https://unpkg.com/vue@3">\</script>
```js const vm = Vue.createApp({ data(){ return{ text: "CLOSE DOOR", open: false, state: "closed" // .closed style } }, watch: { open(evento){ if(evento){ this.state = "opened" // .opened style }else{ this.state = "closed" } } }, template: `
<button @click="open = !open"> {{open ? "CERRAR" : "ABRIR"}} </button> ` }).mount("#app") ```const vm = Vue.createApp({    data(){        return{            text: "CLOSE DOOR",            open: false,            state: "closed" *// .closed style*        }    },    watch: {        open(evento){            if(evento){                *this*.state = "opened" *// .opened style*            }else{                *this*.state = "closed"            }        }    },    template: `        \
\
        \<button @click="open = !open"> {{open ? "CERRAR" : "ABRIR"}} \</button>    `}).mount("#app")
yo hice que cambie la clase que ya tengo en mi hoja css.const vm = Vue.createApp({    data(){        return{            text: "CLOSE DOOR",            open: false,            state: "closed" *// .closed style*        }    },    watch: {        open(evento){            if(evento){                *this*.state = "opened" *// .opened style*            }else{                *this*.state = "closed"            }        }    },    template: `        \
\
        \<button @click="open = !open"> {{open ? "CERRAR" : "ABRIR"}} \</button>    `}).mount("#app")```js const vm = Vue.createApp({ data(){ return{ text: "CLOSE DOOR", open: false, state: "closed" // .closed style } }, watch: { open(evento){ if(evento){ this.state = "opened" // .opened style }else{ this.state = "closed" } } }, template: `
<button @click="open = !open"> {{open ? "CERRAR" : "ABRIR"}} </button> ` }).mount("#app") ```
En mi caso utilicé el mismo watcher que cambia la imagen de la puerta: ```js data() { //funcion que retorna un json return { //watchers textWatch: "Hola Watcher", open: false, imgDoor: "closed.png", classDoor: "closed", } }, watch: { open(value) { if (value) { this.imgDoor = "opened.png"; this.classDoor = "opened"; } else { this.imgDoor = "closed.png"; this.classDoor = "closed"; } }, textWatch(value, old) { console.log("Watcher ", value, " ", old); //muestra el valor actual y el que tuvo antes } }, template: `

Watchers

{{textWatch}}

Door Image
` ```

Esta librería/framework es muy completo y muy sencillo en sus primeros pasos.

que espectáculo estas clases de Diana Martínez, un abrazo!

Si a la profe con su nivel le salen errores, imaginen lo que nos hace falta por recorrer a los que ni tenemos nivel jaja

Es grandioso. Gracias!

<script>
const vm = Vue.createApp({
data(){
return{
text: “Closed Door”,
open: false
};
},
watch: {
open(value){
if(value){
this.text = “Opened Door”;
}else{
this.text = “Closed Door”;
}
}
},
computed: {
status(){
return this.open ? “Cerrar”: “Abrir”;
}
},
template: <div>{{ text }}</div> <button @click="open = !open">{{ status }}</button>
}).mount("#app");
</script>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div id="app">
    <p>{{ text }}</p>
    <button @click="open=!open">{{ label }}</button>
    <p>{{otherLabel}}</p>
    <div>{{now.toLocaleDateString()}}</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
    const vm = Vue.createApp( {
        data() {
            return {
                text: "Puerta cerrada",
                open: false,
                name: "Diego Lipa",
                now: new Date()
            }
        },
        computed: {
            // se puede crear funciones y manipular data
            label() {
                return this.open ? "Cerrar" : "Abrir";
            },
            otherLabel(){
                return this.open? "Ali Mercado":"Diego lipa"
            }
        },
        watch: {
            // watch recibe dos parametros (valor actual, valor anterios)
            open(value, old) {
                console.log(value, old)
                value ? this.text="Puerta abierta" : this.text="Puerta cerrada";
            },
            text(value, old){
                console.log(value, old)
            }
        }
    }).mount("#app");
</script>
</body>
</html>

Apuntes de la clase con todas las variantes vistas

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="https://unpkg.com/vue@next"></script>
    <div id="app"></div>
    <style>
      html,
      body {
        height: 100vh;
        margin: 0;
        font-family: Arial, Helvetica, sans-serif;
      }
      #app,
      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        width: 100%;
        height: 100%;
      }
      button {
        margin-top: 24px;
        border: none;
        background-color: white;
        padding: 8px 24px;
        border-radius: 12px;
      }
      .closed {
        background-color: #eca1a6;
      }
      .open {
        background-color: #b5e7a0;
      }
    </style>
    <script>
      const vm = Vue.createApp({
        data() {
          return {
            text: "Puerta Cerrada",
            open: false,
          };
        },
        watch: {
          open(value) {
            if (value) {
              this.text = "Puerta Abierta";
            } else {
              this.text = "Puerta Cerrada";
            }
          },
        },
        computed: {
          label() {
            return this.open ? "Cerrar" : "Abrir";
          },
          styles() {
            return this.open ? ["open"] : ["closed"];
          },
        },
        //Cuando usamos directivas para pasar las clases vue nos permite pasarle un array con las clases que vayamos a utilizar
        /* template: `
        <div class="container" :class="['open']">
          <h2>{{ text }}</h2>
          <button @click="open= !open">{{ label }}</button>
        </div>
        `, */
        //Tambien nos permite pasar un objeto para poder usar condicionales para aplicar estilos
        /*  template: `
        <div class="container" :class="{'open': open, 'closed': !open}">
          <h2>{{ text }}</h2>
          <button @click="open= !open">{{ label }}</button>
        </div>
        `, */
        //tambien podemos utilizar funcniones computadas para cambiar los estilos
        template: `
        <div class="container" :class="styles">
          <h2>{{ text }}</h2>
          <button @click="open= !open">{{ label }}</button>
        </div>
        `,
      }).mount("#app");
      console.log(vm);
    </script>
  </body>
</html>

Además de la falicidad que da vue para manejar estilos entre otras cosas. sigo aprendiendo de esos errores de novatos!! que hayan más errores para saber como resolverlos en el futuro.

<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="Description" content="Extended Description">
    <meta name="robots" content="index,follow">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Estilos reactivos</title>
    <link rel="stylesheet" href="">

    <style>
        body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        #app, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }
        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }
        .closed {
            background-color: #eca1a6;
        }
        .open {
            background-color: #b5e7a0;
        }
    </style>

</head>

<body>
    <script src="https://unpkg.com/vue@3"></script>

    <div id="app"></div>

    <script>
        const vm = Vue.createApp({
            data() {
                return {
                    textDoor: 'Puerta está cerrada',
                    open: false,
                    // Agregando variable para los estilos de atributo style, debe ser un objeto
                    // En el template debemos agregar el estilo reactivo de esta manera:
                    // v-bind:style="var-styles" o :style="var-styles"
                    // los estilos deben escribirse en camelCase, ejemplo: background-color --> backgroundColor
                    styles: {
                        backgroundColor: '#e5e5e5',
                    },
                };
            },
            watch: {
                open(value) {
                    if (value) {
                        this.textDoor = 'Puerta está abierta';
                        // Color verde si está abierta
                        // this.styles.backgroundColor = '#b5e7a0';
                    } else {
                        this.textDoor = 'Puerta está cerrada';
                        // Color rojo si está cerrada
                        // this.styles.backgroundColor = '#eca1a6';
                    }
                }
            },
            computed: {
                styleStatusBG() {
                    return this.open ? 'open': 'closed';
                },
            },
            /*
            Colocar los estilo con el atributo style
            template: `
                <div class="container" :style="styles">
                    <h2>{{ textDoor }}</h2>
                    <button @click="open = !open">{{ open ? 'cerrar' : 'abrir' }}</button>
                </div>
            `,
            */
            // Colocar los estilo con el atributo class
            // :class="p1" o ":class="['p1','p2','p3'...]"
            // Fromas de agregar la clse en este ejemplo:
            // 1. :class="[open ? 'open' : 'closed']"
            // 2. :class="{ 'open': open, 'closed': !open }"
            // 3. Una propiedad computada :class="styleStatusBG"
            template: `
                <div class="container" :class="styleStatusBG">
                    <h2>{{ textDoor }}</h2>
                    <button @click="open = !open">{{ open ? 'cerrar' : 'abrir' }}</button>
                </div>
            `,
        }).mount('#app');
    </script>

</body>

</html>

Este es mi código actual

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            height: 100vh;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }
        #app, .container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%;
            height: 100%;
        }
        button {
            margin-top: 24px;
            border: none;
            background-color: white;
            padding: 8px 24px;
            border-radius: 12px;
        }
        .closed {
            background-color: #eca1a6;
        }
        .open {
            background-color: #b5e7a0;
        }
    </style>

</head>
<body>
    <script src="https://unpkg.com/vue@next"></script>
    <div id="app">
        
    </div>
    <script>
        const vm = Vue.createApp({
            data() {
                return {
                    text: "Puerta cerrada",
                    opcion: "Abrir",
                    open: false,
                    styles: "open"
                }
            },
            methods: {
                abrir: function() {
                    this.open = !this.open
                }
            },
            watch: {
                open(value) {
                    if (value){
                        this.text = "Puerta abierta"
                        this.opcion = "Cerrar"
                        this.styles = "open"
                        
                    } else {
                        this.text = "Puerta cerrada"
                        this.opcion = "Abrir"
                        this.styles = "closed"
                    }

                }
            },
           
            template: `
            
            <div class="container" :class="styles">
                <h2>{{ text }}</h2>
                <button @click="abrir">{{ opcion }}</button>
            </div>    
            `
        }).mount("#app")
        console.log(vm)
    </script>
</body>
</html>