Vuejs para programadores jQuery. Selects dinámicos y Componentes Vuejs XI

Vuejs para programadores jQuery.  

Selects dinámicos y Componentes Vuejs XI


Este será un post largo. No lo recomiendo leer con prisas. Trataremos varias cosas así que hacer un café y seguimos.




Lo primero que hablaremos es de la asignación de arrays / objetos de JS.


Código de estas pruebas online: https://playcode.io/624524/


Ademas hemos agregado un archivo independiente del proyecto con el código js (recordar que los resultados se ven en console y no en la web)


Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/Copia%20de%20array%20js.html

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/Copia%20de%20array%20js.html


Cuando asignamos una variable a otra JS hace una copia del valor conservando el original, veamos:


let var1 =0

let var2 = var1


var2++


console.log(var1, var2) // 0 1


Esto es lo correcto y esperando. Sin embargo cuando trabajamos con arrays u objetos esto no es así. Veamos un ejemplo (también disponible en el enlace anterior):


let listado = [1,2,3,4,5]

let listado2 = listado


listado2.push(6)


console.log(listado) // (6) [1,2,3,4,5,6]

console.log(listado2) // (6) [1,2,3,4,5,6]


¿Qué ha pasado? Lo que Js hace es una copia por referencia del array u objeto. O sea que no crea un elemento nuevo sino que guarda una referencia al objeto / array original.


Hay caminos para hacer una copia de objetos y/o arrays pero no es una asignación simple. Explico esto porque aunque algunos lo vean como un defecto y otro como una virtud del lenguaje necesitamos entenderlo para operaciones así (también disponible en el enlace anterior):


let opciones = [1,2,3]


function changeArray(info) {

info.push(99)

}


changeArray(opciones)


console.log(opciones) // (4) [1,2,3,99]


Véase que hemos enviado el array a la función y está lo ha modificado internamente, no obstante el cambio ha sido global afectado el array original. Usaremos una particularidad de Js en varias ocasiones y por eso hemos visto esto ahora.


Este proyecto consta de 3 listas y un select. Es una creación dinámica de un select y también son dinámicas las listas (elegidas (las que se elijan en el select), eliminadas (al hacer click en elegidas), y disponibles (al hacer click en eliminadas se agregan a esta lista) ).


Y 2 form Input para agregar a las listas de disponibles y eliminadas y uno más para agregar elementos al select.


Gráficamente es más o menos así:


Vayamos con el código.

Usaremos una vez más un archivo externo. Esta vez para definir dos arrays(disponibles y opciones) con el formato que hasta ahora estábamos usando:


Enlaces:

Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/opciones.js

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/opciones.js


const disponibles = [

{

titulo: 'Rojo',

index: 301

}

...


Código jQuery:


Enlaces:

Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/jQuerySelectDinamico.html

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/jQuerySelectDinamico.html


HTML:

<div class="content">

<div class="row">

<div class="col-4">

<div class="form-group">

<label for="selectInitial">Example select</label>

<select class="form-control" id="selectInitial"></select>

</div>

</div>

<div class="col-4">

<span>Disponibles</span>

<ul class="list-group" id="listAvailable">

</ul>

</div>

<div class="col-4">

<span>Eliminados</span>

<ul class="list-group" id="listDeleted">

</ul>

</div>

</div>

<div class="row top30 special-box">

<div class="col-4">

<div class="form-group">

<label for="fieldSelect">Agrege valores directamente</label>

<div class="input-group mb-2">

<input type="text" class="form-control" id="fieldSelect">

<div class="input-group-append">

<button class="btn btn-primary" id="addSelect">Aceptar</button>

</div>

</div>

</div>

</div>

<div class="col-4">

<div class="form-group">

<label for="fieldAvailable">Agrege valores disponibles</label>

<div class="input-group mb-2">

<input type="text" class="form-control" id="fieldAvailable">

<div class="input-group-append">

<button class="btn btn-primary" id="addAvailable">Aceptar</button>

</div>

</div>

</div>

</div>

<div class="col-4">

<div class="form-group">

<label for="fieldDeleted">Agrege valores a la lista de eliminados</label>

<div class="input-group mb-2">

<input type="text" class="form-control" id="fieldDeleted">

<button class="btn btn-primary" id="addDeleted">Aceptar</button>

</div>

</div>

</div>

</div>

<div class="row">

<div class="col-4">

<span>Elegidos</span>

<ul class="list-group" id="listSelected">

</ul>

</div>

</div>

</div>


En resumen podremos encontrar: 3 listas <ul>. Un select. 3 form input cada uno con un botón.


Veamos el Js:


const available = jQuery('#listAvailable') // List UL de los elementos disponibles

const initial = jQuery('#selectInitial') // Select

const deleted = jQuery('#listDeleted') // Lista UL elemento borrados

const selected = jQuery('#listSelected') // Lista UL de elegidos

const addButtonAvailable = jQuery('#addAvailable') //Botón del form input para agregar elementos a la lista de Disponibles

const addButtonDeleted = jQuery('#addDeleted') // Botón del form input para agregar elementos a la lista de Eliminados

const addButtonSelect = jQuery('#addSelect') // Botón del form input para agregar elementos al select

// En el script externo traemos dos listas (para el select y para los elementos disponibles)

let listElegidos = [] // Lista de los elegidos

let listDeleted = [] // Lista de los eliminados


Veamos primero las funciones templates creadas:


function templateOption({index, titulo}) {

return `<option class="form-control" value="${index}">${titulo}</option>`

}


function templateItemGroup({titulo, index}) {

return `<li class="list-group-item" index="${index}">${titulo}</li>`

}

Tenemos dos casos solamente: <li> y <option> y las construimos usando la desestructuración comentada en el post anterior. En el caso de option guarda el valor único en el campo que tiene para ello llamado value pero en el caso de los li hemos creado un atributo nuevo llamado index para guardar dicho valor.


Como son 4 arrays, la idea ha sido copiar entre arrays y actualizar, regenerando, los elementos de las listas y el select.


Para eso hemos creado una función genérica que mueve un valor de un array a otro. O sea lo copia de donde esta a donde tendría que estar ahora y luego lo elimina del origen:


function modeList(listOrigin, listDestiny, value) {

const index = parseInt(value)

const element = listOrigin.findIndex(item => item.index === index)

if (element === -1) {

return

}

listDestiny.push(listOrigin[element])

listOrigin.splice(element, 1)

}

Esta función recibe dos array y el index del valor que hay que mover de la primer lista a la segunda.


Aclaremos una cosa que puede prestarse a confusión:


findIndex es un método de los arrays de Js que devuelve el lugar que ocupa el primer elemento que cumple el criterio. Por ejemplo:


let datos= [3,5,2,9]


console.log(datos.findIndex(item => item===5)) // nos devolvera 1. Recordemos que contamos desde 0. Y para recuperar ese valor nos vale datos[1]


Este findIndex NADA tiene que ver con nuestros valores index, que usamos como referencia única de cada elemento.


Volviendo a la función:


Como sabemos el index estará en los atributos de los elementos HTML como cadena de texto, así que lo primero que hacemos es convertirlo a un valor entero.

Seguido buscamos el elemento cuyo campo index coincide con el value enviado.


Si no existe salimos de la función sin hacer ningún cambio


Si existe agregamos al array de destino el elemento desde el array original y luego con splice eliminamos el elemento del lugar de origen.


Hablemos de splice:


splice permite agregar o eliminar elementos de un array. La diferencia con push es que se puede colocar el elemento en una posición determinada del array (push siempre coloca el elemento nuevo al final del array)


También permite eliminar una cantidad determinada de valores (no solo uno), aunque splice es un método con muchas posibilidades no lo veremos mucho en esta serie. Aquí lo hemos usado así:


listOrigin.splice(element, 1)


element es la posición del elemento en el array y 1 es la cantidad de elementos que eliminaremos.


Para saber más de splice: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/splice


Observemos que manipulamos arrays sin devolver valores, ya que por la razón que explicáramos al principio del post estamos modificando los arrays originales.


Veamos un ejemplo de uso:


function clickSelectToElegidos() {

modeList(opciones, listElegidos, jQuery('#selectInitial option:selected').val())

updateAll()

}


Este nombre de función es revelador en cuanto a o que hace: mueve un elemento desde el select al array de los elegidos.


modeList(opciones, listElegidos, jQuery('#selectInitial option:selected').val())


Aquí llamamos a la función que explicamos antes. opciones es la lista de elementos del select y listElegidos es la lista de elegidos. El index único es el val() de la opción elegida del select.


De esta manera es sencillo deducir el resto de movimientos entre listas:


function clickDisponibleToSelect(evt) {

modeList(disponibles, opciones, jQuery(evt.target).attr('index'))

updateAll()

}


function clickDeletedToDisponible(evt) {

modeList(listDeleted, disponibles, jQuery(evt.target).attr('index'))

updateAll()

}


function clickElegidosToDeleted(evt) {

modeList(listElegidos, listDeleted, jQuery(evt.target).attr('index'))

updateAll()

}


Son idénticas en teoría de implementación y cambian los arrays origen y destino en cada caso. En estas tres últimas, que son elementos <li> usamos el atributo index (implantado por nosotros en las funciones template) y usamos el evento (evt) (explicado en post anteriores) para obtener el elemento actual.


La asociación de funciones y eventos la establecemos en esta lista:


initial.on('change', clickSelectToElegidos)

available.on('click', clickDisponibleToSelect)

deleted.on('click', clickDeletedToDisponible)

selected.on('click', clickElegidosToDeleted)

Asociando, en el primer caso, al cambio de select y, en el resto de casos, a los click sobre los elementos <li>.


La función updateAll puede ser mejorada en cuanto a que podría tener un update más específico de cada caso y sería lo recomendable para un proyecto de mayor envergadura. En este caso hemos usado una solución muy genérica:


function updateAll() {

initial.empty()

available.empty()

deleted.empty()

selected.empty()

opciones.every(item => initial.append(templateOption(item)))

disponibles.every(item => available.append(templateItemGroup(item)))

listElegidos.every(item => selected.append(templateItemGroup(item)))

listDeleted.every(item => deleted.append(templateItemGroup(item)))

}

Vaciamos TODOS los elementos y les agregamos (usando el template) cada item de la lista correspondiente.

El intercambio entre listas está terminado pero tenemos que completar el proceso por el cual los form inputs agregan valores a las listas.

Pero antes miremos una función:

function findIndexMax() {

let index = 0

let lista = opciones.concat(disponibles, listElegidos, listDeleted)

lista.forEach(item => {

if (item.index > index) {

index = item.index

}

})

return ++index

}

Esta función es para generar un nuevo index único y no estar repitiendo valores.

Primero establecemos un valor a 0, luego creamos una lista única concadenando todas las listas existentes (esto no afectara a las listas originales), para hacer una única rutina de búsqueda en lugar de hacer una rutina de búsqueda por cada lista. Veamos el forEach:


lista.forEach(item => {

if (item.index > index) {

index = item.index

}

})


La lógica es sencilla. Recorremos todos los elementos y comparamos el index de cada uno con el index actual. Si es mayor le asignamos ese valor al index actual y continuamos comparando. De esta manera obtendremos el valor mayor de los index de las listas.


y luego hacemos el return ++index


El símbolo ++ se usa para aumentar en uno un valor determinado y se puede poner antes de la variable o después. Cada posición indica una cosa diferente:


++index => sumar antes de usar la variable

index++ => usar la variable y sumar posteriormente


En el return puede ser irrelevante, ya que resuelve la variable antes de devolver el valor pero quería poner este tema en la mesa. Veamos un ejemplo de uso:


let posicion = 0


console.log(posicion++) // Devuelve 0

console.log(posicion) // Devuelve 1

console.log(++posicion) // Devuelve 2


El primer console.log usa la variable y luego suma el valor, la prueba de ello es el segundo console que sin modificar nada nos devuelve el valor original + 1

En cambio el tercer console nos devuelve la variable con el valor agregado.

Para el siguiente paso son importantes los id's de los form input's:

<input type="text" class="form-control" id="fieldSelect">

<input type="text" class="form-control" id="fieldAvailable">

<input type="text" class="form-control" id="fieldDeleted">


Los 3 comparten la palabra "field" pero lo que sigue es diferente. Luego de cada input hay un botón con id's similares:

<button class="btn btn-primary" id="addSelect">Aceptar</button>

<button class="btn btn-primary" id="addAvailable">Aceptar</button>

<button class="btn btn-primary" id="addDeleted">Aceptar</button>

Que usamos para relacionar una función a cada uno con el evento click:


addButtonAvailable.click(function () {

addGeneral('Available')

})

addButtonDeleted.click(function () {

addGeneral('Deleted')

})

addButtonSelect.click(function () {

addGeneral('Select')

})

En cada evento se llama a la función addGeneral enviando en el parámetro la parte de la palabra que varia en cada form input. Veamos la función:

function addGeneral(type) {

const origen = jQuery('#field' + type)

if (!type || !origen.val()) {

return

}

const element = {

titulo: origen.val(),

index: findIndexMax()

}

origen.val('')

switch (type) {

case 'Select':

opciones.push(element)

break

case 'Deleted':

listDeleted.push(element)

break

case 'Available':

disponibles.push(element)

break

}

updateAll()

}

Definimos una constante que apunta a elemento identificado con #field + el type que enviamos en el parámetro ('Select', 'Deleted' o 'Available') y verificamos el val() de dicho form input. Si está vacío salimos sin modificar nada. Si type es una cadena vacía también sale de la función.

Si esas condiciones no suceden continuamos:

Creamos un elemento nuevo siguiendo la estructura de las listas que estamos usando y asignamos a título el valor del form input y a index el valor de la función findIndexMax() explicada antes


Luego vaciamos el input y usamos un switch case para definir, según el type, en que lista debemos agregar el nuevo elemento. Al final actualizamos todo.


Y ya tenemos la parte de jQuery. Ahora iremos a Vuejs recordando que el js externo es el mismo y que las particularidades de Js nombradas antes siguen siendo válidas en cualquier uso de Js más allá de frameworks o librerías.


Enlaces:


Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/VueJsSelectDinamico.html

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/VueJsSelectDinamico.html


Hablemos de templates y componentes.


La palabra template ha sido bastante usada los últimos tiempos para definir muchas cosas diferentes con un concepto en común: Son plantillas.


En HTML es posible escribir templates para evitar repetir código. Estos dos ejemplos diferentes tratan ese tema:


https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_template

https://developer.mozilla.org/es/docs/Web/HTML/Elemento/template


Básicamente es un código HTML que a través de js puede o no modificar los valores y agregarlo al HTML general según eventos.


Cuando usamos algo más complejo (por ejemplo enviarle parámetros al template) ya hablamos de funcionalidades tipo mustache.js:


https://github.com/janl/mustache.js


Estos templates por supuesto permiten CSS y otras particularidades.


El tercer nivel de los templates es cuando tienen acciones internas para resolver determinados problemas por si mismos. Por ejemplo una lista que reciba como parámetro un array y si hay un click devuelva el elemento sobre el que se cliqueado. En este caso hablamos de componentes.


En este proyecto crearemos el primer componente de Vuejs. Y es importante recordar que no estamos usando el camino normal de un proyecto Vuejs. Solo estamos dando soluciones para casos específicos donde la migración de un proyecto se piensa de forma paulatina de jQuery a Vuejs.


Si se busca buen material de Vue no dejaré de recomendar Escuela Vue: https://escuelavue.es/ con material de alta calidad y GRATUITA.


Sigamos. El componente ha sido definido en un archivo externo, aunque podría definirlo dentro del mismo archivo sobre el que tenemos el código de Vuejs pero de esta manera le haremos un estudio más aislado:


Enlaces:


Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/ListComponent.js

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/ListComponent.js


Veamos el código:


Vue.component('view-lista', {

props: {

listContent: {

type: Array,

require: true,

}

},

template: `<ul class="list-group">

<option v-for="item in listContent" :key="item.index" @click="$emit('update', item)">{{item.titulo}}</option>

</ul>`

})


Vamos paso a paso. Lo primero que tenemos que dar es un nombre al componente para identificarlo, en este caso lo hemos llamado view-lista.

Lo siguiente es definir las props (si es que usara) que no son más que atributos que aceptaran valores de la misma manera que un atributo HTML común.

Hemos definido solo uno, lo hemos llamado listContent, lo hemos definido de tipo array y hemos dicho que si no se le pone el atributo emita un error (require: true).


Antes de continuar veamos la implantación:


<view-lista :list-content="listDeleted" @update="clickDeletedToDisponible"></view-lista>


Si miramos con atención no es más que un elemento HTML nuevo. Los elementos HTML también pueden ser definidos como componentes "naturales" del HTML. Es afectado por el CSS y permite los atributos estándar de cualquier elemento HTML (como class por ejemplo)


La prop definida la usamos exactamente igual que cualquier atributo HTML, ya que los : ya vimos que lo hacemos para definir que el tipo de contenido sea procesado por Vuejs y si fuera un parámetro string, por ejemplo y le pasáramos un mensaje directo no le haría falta.





Todo esto es para que se pierda el miedo y la mística de los componentes porque son muy útiles para evitar repetir código y aumentar las funcionalidades.


Otra cosa que vemos es que la propiedad ha cambiado en la forma de escribirlo:


props: {

listContent: {

...

:list-content="listDeleted"



Esta particularidad de camelCase y kebab-case se explica mejor aqui: https://es-vuejs.github.io/vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case


Volviendo al componente miremos la parte del código HTML:


template: `<ul class="list-group">

<option v-for="item in listContent" :key="item.index" @click="$emit('update', item)">{{item.titulo}}</option>

</ul>`


El primer detalle con las comillas. Nótese que son las mismas que usamos cuando hacemos ${variable} en una cadena de texto de Js. El v-for lo hemos visto muchas veces y en esta ocasión utiliza la prop como origen de los items.


El único misterio real es $emit. Hablemos de ello.


$emit emite un evento. Nosotros hemos trabajados con múltiples eventos. En jQuery a través del método on o con on[click, input, change]="funcion" en el elemento HTML. En Vuejs usamos el arroba(@) para lo mismo.


Conocemos: change, input, click de estos posts pero aún hay muchos más que no hemos usado (Si se quiere hacer un repaso: https://developer.mozilla.org/en-US/docs/Web/Events )

Aquí usamos un evento propio cuando pasa algo relevante: Se ha hecho click en un elemento del HTML (en este caso los <li>)


@click="$emit('update', item)"


hemos llamado al evento update y como parámetro enviamos el item


En la implementación usamos:


@update="clickDeletedToDisponible"


O sea que cuando el componente que hemos creado emita el evento update llamamos a una función (nótese la falta de los parámetros en la asociación de la función al evento)


Un poco más de información aquí:


Fuente de información de Vuejs con CDN y componentes: https://gist.github.com/mrcodedev/741b61abeeb8547de30e7f1661861575

Componentes información oficial: https://es-vuejs.github.io/vuejs.org/v2/guide/components.html


Ahora si empecemos con Vuejs:

Enlaces:


Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/VueJsSelectDinamico.html

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/VueJsSelectDinamico.html


HTML:


<div class="content" id="app">

<div class="row">

<div class="col-4">

<div class="form-group">

<label for="selectInitial">Example select</label>

<select class="form-control" id="selectInitial" v-model="selectElement" @click="clickSelectToElegidos">

<option v-for="item in listOpciones" :key="item.index" :value="item.index">{{item.titulo}}</option>

</select>

</div>

</div>

<div class="col-4">

<span>Disponibles</span>

<view-lista :list-content="listDisponibles" @update="clickDisponibleToSelect"></view-lista>

</div>

<div class="col-4">

<span>Eliminados</span>

<view-lista :list-content="listDeleted" @update="clickDeletedToDisponible"></view-lista>

</div>

</div>

<div class="row top30 special-box">

<div class="col-4">

<div class="form-group">

<label for="fieldSelect">Agrege valores directamente</label>

<div class="input-group mb-2">

<input type="text" class="form-control" id="fieldSelect" v-model="inputSelect">

<div class="input-group-append">

<button class="btn btn-primary" id="addSelect" @click="addButtonSelect()">Aceptar</button>

</div>

</div>

</div>

</div>

<div class="col-4">

<div class="form-group">

<label for="fieldAvailable">Agrege valores disponibles</label>

<div class="input-group mb-2">

<input type="text" class="form-control" id="fieldAvailable" v-model="inputAvailable">

<div class="input-group-append">

<button class="btn btn-primary" id="addAvailable" @click="addButtonAvailable()">Aceptar</button>

</div>

</div>

</div>

</div>

<div class="col-4">

<div class="form-group">

<label for="fieldDeleted">Agrege valores a la lista de eliminados</label>

<div class="input-group mb-2">

<input type="text" class="form-control" id="fieldDeleted" v-model="inputDeleted">

<button class="btn btn-primary" @click="addButtonDeleted()">Aceptar</button>

</div>

</div>

</div>

</div>

<div class="row">

<div class="col-4">

<span>Elegidos</span>

<view-lista :list-content="listElegidos" @update="clickElegidosToDeleted"></view-lista>

</div>

</div>

</div>


Algunos cambios son los ya conocidos (espero) como por ejemplo el select que hace el v-for para crear o el uso del v-model en los form inputs, también los eventos @click en los button.


Esto nos deja libre el camino para centrarnos en el componente que hemos creado y usamos 3 veces, cada vez con una lista nueva y asociando el evento emitido a una función diferente según el caso


Recordar que nos traemos un script extra que es la definición del componente y lo hacemos en esta línea:


<script src="ListComponent.js"></script>


Vayamos al código. Primero las variables:


selectElement: opciones[0].index // apunta al elemento elegido del select, aqui usa el array externo para definir su primer valor igual al index del primer valor de dicha lista

listDisponibles: disponibles // apunta a la lista de disponibles. Su valor inicial lo toma del array externo

listOpciones: opciones // apunta a la lista de opciones (elementos del select). Su valor inicial lo toma del array externo

listElegidos: [] // apunta a la lista de elegidos. Se inicia vacía

listDeleted: [] // apunta a la list de borrados. Se inicia vacía

inputSelect: '' // apunta al contenido del form input para agregar al select

inputDeleted: '' // apunta al contenido del form input para agregar a los eliminados

inputAvailable: '' //apunta al contenido del form input para agregar a los disponibles


Hay código Js que es relativamente igual al que usamos en jQuery:


modeList(listOrigin, listDestiny, value) {

const index = parseInt(value)

const element = listOrigin.findIndex(item => item.index === index)

if (element === -1) {

return

}

listDestiny.push(listOrigin[element])

listOrigin.splice(element, 1)

}

Seguimos usando la particularidad de Js que hablábamos al principio para ahorrar código en el movimiento de elementos entre arrays. Es prácticamente igual que la usada en jQuery


findIndexMax() {

let index = 0

let lista = this.listOpciones.concat(this.listDisponibles, this.listElegidos, this.listDeleted)

lista.forEach(item => {

if (item.index > index) {

index = item.index

}

})

return ++index

}


Aquí los cambios se relacionan más que nada con el uso del this. Por lo demás una vez más conservamos la lógica anterior para buscar un index único.


addGeneral(type) {

switch (type) {

case 'Select':

this.listOpciones.push({

titulo: this.inputSelect,

index: this.findIndexMax()

})

this.inputSelect = ''

break

case 'Deleted':

this.listDeleted.push({

titulo: this.inputDeleted,

index: this.findIndexMax()

})

this.inputDeleted = ''

break

case 'Available':

this.listDisponibles.push({

titulo: this.inputAvailable,

index: this.findIndexMax()

})

this.inputAvailable = ''

break

}

}


El addGeneral de Vuejs cambia en que no debemos buscar un val() ya que usamos variables asociadas a los valores así que lo hacemos todo directamente en el switch case, creamos los nuevos elementos directamente en el push de las listas correspondientes y vaciamos los form input asociando la variable al valor ''


La asociación de los @click en los botones de los form input llevan a funciones muy parecidas a las de jQuery una vez más:


addButtonAvailable () {

this.addGeneral('Available')

}


addButtonDeleted() {

this.addGeneral('Deleted')

}


addButtonSelect() {

this.addGeneral('Select')

}


Que evoca la función anterior.


Y las funciones:


clickSelectToElegidos() {

this.modeList(this.listOpciones, this.listElegidos, parseInt(this.selectElement))

this.selectElement = this.listOpciones[0].index

}


clickDisponibleToSelect({index}) {

this.modeList(this.listDisponibles, this.listOpciones, index)

}


clickDeletedToDisponible({index}) {

this.modeList(this.listDeleted, this.listDisponibles, index)

}


clickElegidosToDeleted({index}) {

this.modeList(this.listElegidos, this.listDeleted, index)

}


Tienen algunos cambios. El más importante es que no es necesario el updateAll. Esto sucede cuando se cambian los contenidos.

La primer función actualiza usando el elemento elegido (la variable contiene el value del elemento elegido que es el index del item)

Y la segunda linea cambia el valor de la variable (porque su valor index ya no vale para esa lista, ya que hemos movido el elemento) para que apunte al primer elemento del select.


Las otras tres funciones usan la desestructuración para recibir el index del item. Veamos el uso de una de ellas:


@update="clickDisponibleToSelect" // Estamos usando el evento del componente que hemos creado.


En el componente hemos definido que este evento tenga como parámetro el item y aquí:


clickDisponibleToSelect({index})


Recogemos el campo index ({}) del objeto item y lo usamos dentro de la función. Hemos hablado de desestructuración en post anteriores.


Hemos usado casi la misma lógica. Hemos ahorrado código Js. Y también ahorrado código HTML con el componente. Seguiremos avanzando en ese tema más adelante. Espero que este post haya sido útil.


El componente no ha necesitado ningún tipo de actualización ni aviso de cambio. El contenido se actualiza cuando el array cambia el contenido. Hemos resuelto el problema de una forma muy directa pero solo es un acercamiento al concepto.


Enlaces:

Codesandbox: https://githubbox.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/indexSelectDinamico.html

GitHub: https://github.com/Gonzalo2310/jQuery-Vuejs/blob/master/Select/Dinamico/indexSelectDinamico.html



Consultas, dudas, comentarios: Slack de PEUM o en Twitter.



No hay comentarios:

Publicar un comentario

Vuejs para programadores jQuery. Tablas simple. Paginación. XV

Vuejs para programadores jQuery. Tablas simple. Paginación. XV Hoy veremos el código de una tabla sencilla con paginación y modal para ver ...