15. proyecto [vuejs-13]: actualización de un componente, uso de una sesión
El proyecto [vuejs-13] retoma el proyecto [vuejs-12] e introduce la siguiente modificación: la tabla mostrada por la tabla HTML se define en un objeto [session] conocido por todos los componentes. Se trata, por tanto, de una forma de compartir información entre componentes. Este concepto se inspira directamente en la sesión web. Utilizamos el método del plugin para que este objeto compartido esté disponible en un atributo [Vue.$session].
La estructura del proyecto es la siguiente:

15.1. El objeto [session]
El objeto [session], compartido por todos los componentes, se define en el script [./session.js]:
const session = {
// lista de simulaciones
get lignes() {
return this._lignes;
},
// generación de la lista de simulaciones
generateLignes() {
this._lignes =
[
{ id: 3, marié: "oui", enfants: 2, salaire: 35000, impôt: 1200 },
{ id: 5, marié: "non", enfants: 2, salaire: 35000, impôt: 1900 },
{ id: 7, marié: "non", enfants: 0, salaire: 30000, impôt: 2000 }
]
},
// eliminación de la línea n.º índice
deleteLigne(index) {
this._lignes.splice(index, 1);
}
}
// exportación del objeto [session]
export default session;
15.2. El complemento [./plugins/pluginSession]
El script [pluginSession] es el siguiente:
export default {
install(Vue, session) {
// añade una propiedad [$session] a la clase vista
Object.defineProperty(Vue.prototype, '$session', {
// cuando se hace referencia a Vue.$session, se devuelve el segundo parámetro [session] del método [install]
get: () => session,
})
}
}
- línea 4: el objeto compartido [session] estará disponible en la propiedad [$session] de todos los componentes;
15.3. El script principal [main.js]
El script principal [main.js] es el siguiente:
// importaciones
import Vue from 'vue'
import App from './App.vue'
// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);
// bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// sesión
import session from './session';
import pluginSession from './plugins/pluginSession'
Vue.use(pluginSession, session)
// configuración
Vue.config.productionTip = false
// instanciación del proyecto [App]
new Vue({
name: "app",
render: h => h(App),
}).$mount('#app')
- líneas 14-16: el plugin [pluginSession] se integra en el framework [Vue.js];
- después de la línea 16, el atributo [$session] está disponible para todos los componentes;
15.4. La vista principal [App]
La vista [App] es ahora la siguiente:
<template>
<div class="container">
<b-card>
<!-- mensaje -->
<b-alert show variant="success" align="center">
<h4>[vuejs-13] : mise à jour d'un composant, partage des données avec une session</h4>
</b-alert>
<!-- tabla HTML -->
<Table @updateTable="updateTable" :key="versionTable"/>
</b-card>
</div>
</template>
<script>
import Table from "./components/Table";
export default {
// nombre
name: "app",
// componentes
components: {
Table
},
// estado interno
data() {
return {
// versión de tabla
versionTable: 1
};
},
// métodos
methods: {
updateTable() {
// eslint-disable-next-line
console.log("App updateTable");
// incremento de la versión de la tabla
this.versionTable++;
}
}
};
</script>
Comentarios
- La vista [App] ya no gestiona la tabla mostrada por el componente [Table] de la línea 9;
- línea 9: el componente [Table] emite el evento [updateTable], que solicita que se regenere el componente [Table]. Una forma de hacerlo es utilizar el atributo [:key]. A este atributo se le asigna un valor modificable. Cada vez que se modifica, se regenera el componente [Table];
- línea 9: el valor del atributo [:key] es el atributo [versionTable] de la línea 27. El método [updateTable] (líneas 33-38) se encarga de regenerar el componente [Table] de la línea 9. Para ello, el método incrementa el valor del atributo [:key] del componente [Table], línea 37. A continuación, el componente [Table] se regenera automáticamente;
15.5. El componente [Table]
El componente [Table] evoluciona de la siguiente manera:
<template>
<div>
<!-- lista vacía -->
<template v-if="lignes.length==0">
<b-alert show variant="warning">
<h4>Votre liste de simulations est vide</h4>
</b-alert>
<!-- botón de recarga-->
<b-button variant="primary" @click="rechargerListe">Recharger la liste</b-button>
</template>
<!-- lista no vacía-->
<template v-if="lignes.length!=0">
<b-alert show variant="primary" v-if="lignes.length==0">
<h4>Liste de vos simulations</h4>
</b-alert>
<!-- tabla de simulaciones -->
<b-table striped hover responsive :items="lignes" :fields="fields">
<template v-slot:cell(action)="row">
<b-button variant="link" @click="supprimerLigne(row.index)">Supprimer</b-button>
</template>
</b-table>
</template>
</div>
</template>
<script>
export default {
// estado calculado
computed: {
lignes() {
return this.$session.lignes;
}
},
// estado interno
data() {
return {
fields: [
{ label: "#", key: "id" },
{ label: "Marié", key: "marié" },
{ label: "Nombre d'enfants", key: "enfants" },
{ label: "Salaire", key: "salaire" },
{ label: "Impôt", key: "impôt" },
{ label: "", key: "action" }
]
};
},
// métodos
methods: {
supprimerLigne(index) {
// eslint-disable-next-line
console.log("Table supprimerLigne", index);
// se elimina la línea
this.$session.deleteLigne(index);
// se solicita al componente padre que actualice la vista
this.$emit("updateTable");
},
// recarga de la lista mostrada
rechargerListe() {
// eslint-disable-next-line
console.log("Table rechargerListe");
// se vuelve a generar la lista de simulaciones
this.$session.generateLignes();
// se solicita al componente padre que actualice la vista
this.$emit("updateTable");
}
}
};
</script>
Comentarios:
- el atributo [lignes] (líneas 4, 12, 17) ya no es un parámetro fijado por el componente padre, sino un atributo calculado del componente [Table] (líneas 30-32). [lignes] es, por tanto, la matriz [$session.lignes] (línea 31);
- líneas 49-56: el método [supprimerLigne] elimina una línea de la tabla [$session.lignes]. Por defecto, esta eliminación no modifica la visualización de la tabla HTML. De hecho, los elementos de [$session] no son reactivos: su modificación no se refleja en los componentes que los utilizan. Por este motivo, el componente [Table] solicita a su padre que lo regenere mediante el evento [updateTable] (línea 55). Hemos visto que el componente padre incrementará entonces el atributo [:key] del componente [Table] para forzar su regeneración;
- líneas 58-65: el método [rechargerListe] solicita al objeto [$session] que regenere la tabla [$session.lignes]. Por la misma razón que antes, esta modificación de [$session.liste] no cambia, por defecto, la visualización de la tabla HTML. Por este motivo, el componente [Table] solicita a su padre que lo regenere mediante el evento [updateTable] (línea 64).
15.6. Ejecución del proyecto

Se obtienen los mismos resultados que en el proyecto [vuejs-12].