15. proyecto [vuejs-13]: actualización de un componente, uso de una sesión
El proyecto [vuejs-13] retoma el proyecto [vuejs-12] e incorpora la siguiente modificación: la tabla que muestra la tabla HTML se define en un objeto [session] conocido por todos los componentes. Por lo tanto, es una forma de compartir información entre componentes. Este concepto se inspira directamente en la sesión web. Utilizamos el método del complemento para hacer 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) {
// agrega una propiedad [$session] a la clase vista
Object.defineProperty(Vue.prototype, '$session', {
// cuando se hace referencia a Vue.$session se hace referencia, 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 complemento [pluginSession] se integra en el marco [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] ahora es 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 la tabla
versionTable: 1
};
},
// métodos
methods: {
updateTable() {
// eslint-desactivar-línea-siguiente
console.log("App updateTable");
// incremento de la versión de la tabla
this.versionTable++;
}
}
};
</script>
Comentarios
- La vista [App] ya no gestiona la tabla que muestra 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. El componente [Table] se regenera entonces 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 le pide 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 regenera la lista de simulaciones
this.$session.generateLignes();
// se le pide 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 establecido por el componente padre, sino un atributo calculado del componente [Table] (líneas 30-32). [lignes] es, por lo tanto, la tabla [$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: sus modificaciones no se reflejan en los componentes que los utilizan. Por esta razón, el componente [Table] solicita a su componente padre que lo regenere mediante el evento [updateTable] (línea 55). Ya vimos que el componente padre incrementaría 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 componente 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].