Hola 👋! Parece que me perdido un poco por aquí.
Hoy les voy a enseñar a estilizar un checkbox con Vue.js, para que lo puedan utilizar en cualquiera de sus proyectos.
Antes de comenzar, para el diseño me he basado en algunas (no todas) las directrices de este UI Kit: Now UI
Ahora si, vamos a ver como hacerlo !
Que es Vue.js?
Vue.js es un marco JavaScript de código abierto modelo-vista-vista-modelo para construir interfaces de usuario y aplicaciones de una sola página. Fue creado por Evan You, y lo mantienen él y el resto de los miembros activos del equipo central provenientes de varias compañías como Netlify y Netguru.
Diseñando el template !
Si has usado Angular, Vue se te hará muy familiar, ya que ambos utilizan un sistema de templates que separan la vista de la lógica.
Lo primero que haremos será envolver la etiqueta <input />
dentro de una etiqueta <label>
, le asignamos role=button
para que actue como un botón, esto se denomina control etiquetado.
<template>
<label role="button">
<input type="checkbox" />
</label>
</template>
Además crearemos un div que nos va otorgar un efecto de Switch, le colocaremos como hija una etiqueta que nos muestre el estado del checkbox; utilizaremos <span>
.
<template>
<label role="button">
<input type="checkbox" />
<div>
<span>on|off</span>
</div>
</label>
</template>
Para terminar, necesitamos agregar las clases css (ya las vamos crear), el v-model
para crear el binding bidireccional, una función v-on:change | @change
que nos provee Vue, y una variable label
donde mostraremos el estado del switch.
Fijense que en el
div
, además de la propiedadclass
he usado:class
para intercambiar entre los estilos on y off.
Ya tenemos nuestro template terminado 🎉 !
<template>
<label class="switch" role="button">
<input
type="checkbox"
:value="active"
v-model="checked"
@change="update"
/>
<div
class="circle"
:class="{
'circle-on': checked,
'circle-off': !checked
}"
>
<span>{{ label }}</span>
</div>
</label>
</template>
Codificando el script !
Ya tenemos el template terminado, pero por si solo no va a hacer nada. Ahora es el momento de darle la funcionalidad ⚙.
Lo que más me gusta de Vue, es que tienes un solo objeto con la funcionalidad separada, esto nos permite entender facilmente como esta construido el componente.
Empecemos declarando las variables que vamos a necesitar para hacer funcionar nuestro componente.
<script>
export default {
data() {
return {
checked: true,
label: "On",
active: 1,
dataOn: "On",
dataOff: "Off"
};
},
</script>
👁🗨 Si queremos que nuestro componente sea más personalizable con el texto en
label
, y elvalue
necesitamos convertirdataOn
,dataOff
yactive
en propiedades.
<script>
export default {
props: {
dataOn: String,
dataOff: String
active: Number,
}
data() {
return {
checked: true,
label: "On",
};
},
</script>
Cada vez que nuestro componente se inicialice, utilizaremos el hook created
. Esto pertenece al ciclo de vida del componente Vue. En el hook vamos inicializar las variables checked
y label
.
👁🗨 Para acceder a las variables de data, props y funciones necesitamos la palabra reservada
this
.
<script>
export default {
data() {
...
},
mounted() {
this.checked = Boolean(this.active);
this.label = this.checked ? this.dataOn : this.dataOff;
},
};
</script>
Antes, en el template habíamos definido una función update
, ahora es el momento de crearla. Todas la funciones se declaran dentro de la opción methods
de Vue. La función update
simplemente se va a encargar de actualizar la variable label
cuando cambie el valor de checked
.
<script>
export default {
data() {
...
},
mounted() {
...
},
methods: {
update() {
this.label = this.checked ? this.dataOn : this.dataOff;
}
}
};
</script>
Ya tenemos la lógica del switch 🎊!
Si te perdiste, así tenemos la parte JavaScript.
<script>
export default {
data() {
return {
checked: true,
label: "",
active: 1,
dataOn: "On",
dataOff: 'Off'
};
},
mounted() {
this.checked = Boolean(this.active);
// Podemos reutilizar la función update ya que el código es el mismo.
this.update();
},
methods: {
update() {
this.label = this.checked ? this.dataOn : this.dataOff;
}
}
};
</script>
Agregando estilos con Sass !
Esta es la parte final, aunque tengamos el template y la funcionalidad, tenemos que hacer que se vea elegante. En lo personal me gusta Sass, pero puedes utilizar Stylus, Less o simplemente css.
Primero, vamos a definir un par de variables 🟩 (que luego podrás personalizar).
<style lang="scss">
$default: black;
$active: #f96332;
$inactive: #6c757d;
$text: #9d9d9d;
$text-hover: white;
$size: 2.5rem; // font-size
$w: 300px; // largo del elemento
$h: 100px; // alto del elemento
$circle: $h - 4; // tamaño del div
$toggle-dis: $w - $circle - 2; // la distancia que va a recorrer el div para lograr el efecto de switch
</style>
Vamos a deshacernos del input
que viene por defecto. Hay que tomar en cuenta que debemos aplicar esta regla para el elemento dentro de la clase switch
.
<style lang="scss">
...
.switch {
& input {
display: none;
}
}
</style>
Ahora ya somos libres de aplicar los estilos. Les colocaré todo el código css para no abrumarlos 👾.
<style lang="scss">
$default: black;
$active: #f96332;
$inactive: #6c757d;
$text: #9d9d9d;
$text-hover: white;
$size: 2.5rem;
$w: 300px;
$h: 100px;
$circle: $h - 4;
$toggle-dis: $w - $circle - 2;
.switch {
position: relative;
display: inline-block;
width: $w;
height: $h;
border-radius: 100px;
.circle {
display: flex;
align-items: center;
width: 100%;
height: $h - 2;
border-radius: 100px;
background-color: $default;
& > span {
font-size: $size;
color: $text;
padding-left: $h + 4;
}
&::before {
position: absolute;
content: "";
height: $circle;
width: $circle;
left: 1px;
top: 1px;
border-radius: 100px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
&:hover {
background-color: lighten($default, 20);
& > span {
color: $text-hover;
}
}
}
.circle-on {
background-color: $active;
& > span {
color: white;
}
&:hover {
background-color: white;
border: 1px $active solid;
&::before {
background-color: $active;
}
& > span {
color: $active;
}
}
}
.circle-off {
background-color: $inactive;
& > span {
color: white;
}
&:hover {
background-color: white;
border: 1px $inactive solid;
&::before {
background-color: $inactive;
}
& > span {
color: $inactive;
}
}
}
& input {
display: none;
&:checked + .circle:before {
-webkit-transform: translateX($toggle-dis);
-ms-transform: translateX($toggle-dis);
transform: translateX($toggle-dis);
}
}
}
</style>
Resultado final
Si seguimos todos los pasos, tendremos nuestro switch listo para funcionar 🏁.
Este ejemplo lo puedes desarrollar tanto en Angular como en React. La lógica en sí es la misma.
Proximamente estaré subiendo algo nuevo, espero librarme de la U y traerles más contenido !
Nos vemos codeando 👨💻.