Qué son las Propiedades Computadas en Vue.js (Computed Properties)

Las propiedades computadas en Vue.js son parecidas a las propiedades normales (o datos), pero con una diferencia importante: su valor depende de otras propiedades. Esto significa que si una de esas propiedades cambia, la propiedad computada se actualiza automáticamente. Son reactivas, así que no hace falta que tú las actualices manualmente, Vue lo hace por ti.

Ejemplo 1

Imagina que estás creando una pequeña calculadora para saber cuánto pagarás por un producto con IVA incluido. En lugar de hacer el cálculo manual o en una función cada vez que cambien los valores, puedes usar una propiedad computada que se actualice automáticamente cuando cambie el precio o el porcentaje del IVA.
Así Vue se encarga de todo por ti, y tú solo te enfocas en mostrar el resultado.

<template>
  <h1>Calcular IVA(Impuesto al Valor Agregado)</h1>

  <label>Precio(sin IVA)</label>
  <input type="number" placeholder="precio" v-model="precio">
  <br>
  <label>Porcentaje del IVA(Ingresar numero entero)</label>
  <input type="number" placeholder="Porcentaje IVA" v-model="porcentajeIva">
  <br>
  <p><strong>Precio con IVA:</strong> {{ precioConIva }}</p>
</template>


<script setup>
import { ref, computed } from 'vue';

// Se define la propiedad `precio` como reactiva usando ref().
const precio = ref(0);
//Se define la propiedad `porcentajeIva` como reactiva usando ref().
const porcentajeIva = ref(0);

// La propiedad `precioConIva` es computed y recalcula su valor automáticamente
const precioConIva = computed(() => {

  //Se calcula el impuesto multiplicando el precio por la division del `porcentajeIva` entre 100 para obtener el valor en decimal
  const impuesto = precio.value*(porcentajeIva.value/100);
  //El resultado del precio con el IVA incluido 

  const resultado = precio.value+impuesto;
  return resultado; // Redondea a 2 decimales
});
</script>

Ejemplo 2

Supongamos que queremos calcular el promedio de tres notas: tareas, laboratorio y examen. Lo lógico sería sumar las tres y dividir entre 3, pero queremos que este promedio se actualice automáticamente cada vez que cambiemos alguna nota. Para eso, usamos una propiedad computada en Vue.js.

<template>
  <h1>Calcular Promedio</h1>

  <label>Tareas:</label>
  <input type="number" placeholder="Tareas" v-model="tareas">
  <br>

  <label>Laboratorio:</label>
  <input type="number" placeholder="Laboratorio" v-model="laboratorio">
  <br>

  <label>Examen:</label>
  <input type="number" placeholder="Examen" v-model="examen">
  <br>

  <p><strong>Promedio:</strong> {{ promedio }}</p>
</template>


<script setup>
import { ref, computed } from 'vue';

// Se definen las propiedades `tareas`,`laboratorio`,`examen` reactivas usando ref()
const tareas = ref(0);
const laboratorio = ref(0);
const examen = ref(0);

// La propiedad `promedio` es computed y recalcula su valor automáticamente
const promedio = computed(() => {
  const resultado = (tareas.value + laboratorio.value + examen.value) / 3;
  return resultado.toFixed(2); // Redondea a 2 decimales
});
</script>

Propiedades computadas vs métodos

las propiedades computadas y los métodos se escriben de diferente manera pero ellos funcionan de diferente manera.

Métodos:
Se ejecutan cuando son llamados, normalmente a través de un evento (como un clic o una acción del usuario). Esto significa que el cálculo o cambio de valor se hace de manera manual, ya que depende de que algo lo active.

<template>
  <h1>Calcular Promedio con Método</h1>

  <label>Tareas:</label>
  <input type="number" placeholder="Tareas" v-model="tareas">
  <br>

  <label>Laboratorio:</label>
  <input type="number" placeholder="Laboratorio" v-model="laboratorio">
  <br>

  <label>Examen:</label>
  <input type="number" placeholder="Examen" v-model="examen">
  <br>

  <button @click="calcularPromedio">Calcular Promedio</button>
  <p><strong>Promedio:</strong> {{ promedio }}</p>
</template>

<script setup>
import { ref } from 'vue';

const tareas = ref(0);
const laboratorio = ref(0);
const examen = ref(0);
const promedio = ref(0);

const calcularPromedio = () => {
  const resultado = (tareas.value + laboratorio.value + examen.value) / 3;
  promedio.value = resultado.toFixed(2);
};
</script>

En el ejemplo anterior, para obtener el promedio final, es necesario presionar el botón ‘Calcular Promedio’. Si no se ejecuta el método calcularPromedio(), no habrá ningún resultado. El promedio no se genera de forma automática, sino que requiere una acción del usuario para actualizarse.

Propiedades Computadas:
Por otro lado, las propiedades computadas son dinámicas: se actualizan automáticamente cada vez que cambia alguna de las propiedades de las que dependen.
Tomemos como ejemplo el cálculo del promedio: si cambiamos el valor de tareas, laboratorio o examen, el promedio se actualiza solo, sin necesidad de hacer clic en nada o llamar a una función. Vue se encarga de todo.

getters y setters en propiedades computadas

Normalmente, cuando usamos propiedades computadas en Vue, solo escribimos una función que devuelve un valor. Eso sería el getter. Pero también se puede agregar un setter, que nos permite actualizar datos cuando esa propiedad cambia.

En pocas palabras:

El getter sirve para mostrar un valor.

El setter sirve para cambiar otros valores cuando modificamos ese valor computado.

Ejemplo

Imagínate que tienes el nombre y el apellido por separado, pero quieres mostrar el nombre completo y, además, poder cambiarlo desde un solo campo.
Con un get y un set, puedes hacer eso fácilmente: mostrar el nombre completo, y también actualizar el nombre y el apellido si alguien escribe un nuevo nombre completo.

<template>
  <h1>App</h1>
</template>

<script setup>
import { ref, computed } from 'vue'

// Se definen dos propiedades reactivas usando ref()
const nombre = ref('Jose')
const apellido = ref('Ramirez')

// La propiedad `nombreCompleto` es un computed con getter y setter
const nombreCompleto = computed({
  get() {
    // El getter nos permite obtener el valor de la propiedad,
    // en este caso, la concatenación de `nombre` y `apellido`
    return nombre.value + ' ' + apellido.value
  },
  set(nuevoNombre) {
    // Usamos la desestructuración de arrays para dividir `nuevoNombre`
    // y asignarlo a `nombre` y `apellido`
    [nombre.value, apellido.value] = nuevoNombre.split(' ')
  }
})

// Mostramos el nombre completo usando los valores iniciales
console.log(nombreCompleto.value) // "Jose Ramirez"

// Se asigna un nuevo nombre completo
nombreCompleto.value = 'Maria Garcia'

// Se imprime el nuevo nombre completo después del cambio
console.log(nombreCompleto.value) // "Maria Garcia"
</script>

Conclusión

Las propiedades computadas con getters y setters nos permiten manejar de manera sencilla valores derivados y a la vez tener control sobre cómo modificarlos. Son una herramienta poderosa cuando necesitamos que los datos se sincronicen automáticamente sin tener que escribir lógica adicional. Además, facilitan la interacción con los usuarios, permitiendo actualizar y mostrar información sin perder la claridad y simplicidad en el código.


CodeIgniter 4 Rutas:Uso de marcadores.

CodeIgniter 4 nos proporciona la posibilidad de definir las rutas de nuestra aplicación a nuestra conveniencia haciendo uso de marcadores a la hora de especificar una ruta. Esto permite enviar y recibir parámetros a través de la URL de manera controlada y segura.

Tipos de Rutas en CodeIgniter 4

CodeIgniter 4 cuenta con dos tipos principales de enrutamiento:

  • Enrutamiento de Ruta Definida: Permite definir rutas específicas que están enlazadas a métodos de controladores.
  • Enrutamiento Automático: Permite que el sistema determine la ruta basada en los segmentos de la URL automáticamente.

En este tutorial, nos enfocaremos en el Enrutamiento de Ruta Definida y el uso de marcadores.

Definir Rutas con Marcadores

Para definir una ruta en CodeIgniter 4, usamos el archivo Routes.php ubicado en el directorio app/Config. Aquí podemos crear una instancia de la clase RouteCollection ($routes) y definir nuestras rutas con marcadores.

Ejemplo de Ruta con Marcador Numérico

$routes->get('miruta/(:num)','Micontrolador::miMetodo/$1');

En este ejemplo:

Micontrolador::miMetodo/$1 define el controlador y método que manejará la solicitud, pasando el parámetro capturado.

miruta es la vista a la que queremos acceder.

(:num) es un marcador que indica que el parámetro es un número entero.

Ejemplo Práctico

Paso 1: Crear el Controlador

En el directorio app/Controllers, creamos un archivo Micontrolador.php:

<?php 
//usamos el espacio de nombre Controllers
namespace App\Controllers;
class Micontrolador extends BaseController
{
    //creamos un metodo que recibira un parametro en este caso $parametro.
    public function miMetodo($parametro)
    {
        //creamos un array $data con el parametro recibido.
        $data['parametro']=$aparametro;
        //retornamos nuestra vista junto al array $data que creamos.
        return view('miVista',$data);
    }
}

Paso 2: Crear la Vista

En el directorio app/Views, creamos un archivo miVista.php:

<!DOCTYPE html>
<html>
<head>
<title>CodeIgniter</title>
</head>
<body>
<h3>El parametro >
<?php
//imprimimos el parametro que recibimos desde nuestro controlador
 echo $parametro; 
 ?>
 </h3>
</body>
</html>

Paso 3: Definir la Ruta

En app/Config/Routes.php, añadimos:

$routes->get('miruta/(:num)','Micontrolador::miMetodo/$1');

Paso 4: Probar la Ruta

En el navegador, ingresamos la siguiente URL:

http://localhost/ci/public/miruta/2


Esto debería mostrar el valor del parámetro en la vista.

Uso de Múltiples Marcadores

Ejemplo con Dos Parámetros Numéricos

$routes->get('miruta/(:num)/(:num)','Micontrolador::miMetodo/$1/$2');

Controlador:

public function miMetodo($p1,$p2)
    {
        //creamos un array $data con los dos parametros.
        $data['p1']=$p1;
        $data['p2']=$p2;
        //retornamos nuestra vista junto al array $data que creamos.
        return view('miVista',$data);
    }

URL

http://localhost/ci/public/miruta/2/2

Tipos de Parámetros

Parámetros Alfabéticos

Pasar parámetro como cadena de caracteres alfabéticos seria de la siguiente forma

$routes->get('miruta/(:alpha)','Micontrolador::miMetodo/$1');

URL:

http://localhost/ci/public/miruta/joe

Parámetros Alfanuméricos

Pasar parámetro como cadena de caracteres alfanuméricos seria de la siguiente forma

$routes->get('miruta/(:alphanum)','Micontrolador::miMetodo/$1');

URL

http://localhost/ci/public/miruta/parametro1

Combinando tipos de parámetros  

podemos definir mas de un tipo de parámetro al crear una ruta, por ejemplo

$routes->get('miruta/(:alpha)/(:num)','Micontrolador::miMetodo/$1/$2');

URL

http://localhost/ci/public/miruta/joe/123

Uso de Expresiones Regulares

Existe la posibilidad de que al definir las rutas deseamos especificar de manera mas exacta el tipo de parámetro, por ejemplo

$routes->get('miruta/(^[0-9_]+$)','Micontrolador::miMetodo/$1');

Especificamos en la ruta que se aceptara un parámetro que solo contenga enteros y guion bajo, de esta forma se puede ser mas especifico, otro ejemplo

$routes->get('miruta/(^[a-zA-Z0-9_]+$)','Micontrolador::miMetodo/$1');

 En este ejemplo definimos que el parámetro  debe ser alfanumérico que contenga caracteres alfabéticos,enteros y guion bajo. 

Definir Marcadores Propios

CodeIgniter nos ofrece la posibilidad de definir nuestros propios marcadores que se adapten a la necesidades de la aplicación.

Ejemplo parctico

Definimos nuestro marcador de la siguiente manera usando el método addPlaceholder()

$routes->addPlaceholder('miMarcador','\w+');

Definimos nuestra ruta usando el marcador que ya definimos anteriormente

$routes->get('miruta/(:miMarcador)','Micontrolador::miMetodo/$1');

Uso del Marcador :any

Es el marcador permite enviar múltiples parámetros y de distinto tipo a la vez, por ejemplo podríamos necesitar información de un producto por marca,color,tamaño de la siguiente forma

http://localhost/ci/public/producto/abc/azul/mediano

Podemos observar a la palabra producto como la ruta y lo que sigue después de la barra diagonal son los parámetros que recibirá el controlador abc/azul/mediano.

Por ejemplo crearemos una ruta que con el método :any  procesaremos con nuestro controlador los parámetros recibidos para luego mostrarlos en la vista en el siguiente ejemplo.

Paso 1.

En nuestro controlador creamos el método showProducto()

<?php 
namespace App\Controllers;
use CodeIgniter\Controller;
class Micontrolador extends BaseController
{
    public function showProducto($marca=false,$color=false,$tamano=false)
    {
        //Retornamos nuestra vista.
        $data['marca']=$marca;
        $data['color']=$color;
        $data['tamano']=$tamano;
        return view('miVista',$data);
    }
}
?>

Paso 2.

Editamos nuestra vista de la siguiente forma

<!DOCTYPE html>
<html>
<head>
    <title>CodeIgniter</title>
</head>
<body>
    <?php 
    echo '<h3>marca='.$marca.'</h3>';
    echo '<h3>color='.$color.'</h3>';
    echo '<h3>tamaño='.$tamano.'</h3>';
    ?>
</body>
</html>

Paso 3.

Definiendo la ruta de la siguiente manera en nuestro archivo Routes.php

$routes->get('producto/(:any)',Micontrolador::showProducto/$1);

Paso 4.

Probando en el navegador colocamos la url de la siguiente forma

http://localhost/ci/public/producto/abc/azul/mediano

Obtendremos en nuestro navegador el siguiente resultado

Podríamos escribir la url de esta forma y igual funcionaria porque el marcador :any permite el envió de múltiples parámetros a la vez podrían ser 1,2 o 3 parámetros, permitiendo ademas que sean de diferente tipo, por ejemplo alfabéticos, alfanuméricos o enteros.

http://localhost/ci/public/producto/abc/123/456

Como podemos observar cuando escribimos las url en nuestro navegador luego de la palabra producto enviamos 3 parámetros separados por una barra diagonal “/” los cuales recibe nuestro controlador en el método showProducto() retornando la vista y los parámetro que le brindamos a través de la url 

Pero y si solo le enviamos 2 parámetros de la siguiente manera?

http://localhost/ci/public/producto/abc/azul/

Obtendríamos el siguiente resultado en el navegador,porque al definir los parámetros como false en el método showProducto() podemos enviar 1,2 o 3 parámetros y nuestra aplicación seguirá funcionando

Prueba al  enviar solo un parámetro 

http://localhost/ci/public/producto/abc/

El resultado seria el siguiente

Como podemos observar funciona aunque solo enviemos un parámetro.

Lista de Argumentos de Longitud Variable

Se puede pasar una lista de argumentos dinámica, siendo que necesitemos pasar un numero indeterminado de parámetros a nuestra función. 

modificando el método showProducto() de la forma

<?php 
namespace App\Controllers;
use CodeIgniter\Controller;
class Micontrolador extends BaseController
{
    public function showProducto(...$parametros)
    {
        $data['parametros']=$parametros;
        return view('miVista',$data);
    }
}
?>

Modificando nuestra vista de la forma

<!DOCTYPE html>
<html>
<head>
<title>CodeIgniter</title>
</head>
<body>
<?php 
    foreach($parametros as $parametro){
        echo '<h3>Parametro => '.$parametro.'</h3>';
    }
?>
</body>
</html>

Ponemos a prueba en nuestro navegador

Escribimos en nuestro navegador la siguiente url

http://localhost/ci/public/producto/abc/azul/mediano

Obteniendo el siguiente resultado:


Como solucionar el error Cache unable to write to «/var/www/html/ci/writable/cache/» de CodeIgniter 4 en apache linux

Introducción

Uno de los primeros errores que puedes encontrar al trabajar con CodeIgniter en Linux es el mensaje: “Cache unable to write to «/var/www/html/ci/writable/cache/»”. Este problema es común para los nuevos usuarios de CodeIgniter en Linux, aunque no tanto en Windows.

¿Por qué ocurre este error?

La causa principal de este error son los permisos de directorios en Linux. Dependiendo de la distribución que uses (Ubuntu, Debian, Mint, Arch, Fedora), el servidor web puede tener diferentes nombres (por ejemplo, en Fedora se llama httpd en lugar de apache).

Como Solucionarlo?

La solución es otorgar permisos de escritura y lectura al usuario del servidor web para el directorio writable de el proyecto CodeIgniter.

pero que es el usuario del servidor web?

la respuesta es «una cuenta de usuario en el sistema operativo que se utiliza para ejecutar el servicio de apache. Este usuario tiene permisos específicos y limitados para garantizar la seguridad del servidor web».

necesitamos otorgarle permisos de escritura y lectura al usuario del servidor web, del el directorio writable de nuestro proyecto de CodeIgniter,para ello lo asignaremos como el propietario del directorio writable y le concederemos los permisos de escritura y lectura.

Asignar al www-data como propietario del directorio writable

Basta con ejecutar el siguiente comando en nuestra terminal de Linux.

En Debian,Ubuntu

sudo chown www-data:www-data -R /var/www/html/codeigniter/writable

En fedora

sudo chown apache:apache -R /var/www/html/codeigniter/writable

En ArchLinux

sudo chown http:http -R /var/www/html/codeigniter/writable

El comando chown permite cambiar el propietario y grupo del directorio.

Asignamos lo permisos

En esta parte solo basta con otorgarle los permisos necesarios al directorio writable,de la siguiente forma.

sudo chmod 755 /var/www/html/codeigniter/writable/

El comando chmod sirve para cambiar los permisos de un archivo o carpeta. Para usarlo, solo tienes que decir qué permisos quieres y a qué archivo o archivos se los quieres cambiar.con el 755 como configuración de permisos El dueño de la carpeta puede hacer lo que quiera con ella. Los demás solo pueden ver lo que hay dentro, pero no pueden añadir ni borrar archivos. Este tipo de configuración es común para carpetas que quieres compartir con otros.