Skip to content

14. Проєкт [vuejs-12]: управління таблицями HTML

Структура проекту [vuejs-12] така:

Image

14.1. Головний скрипт [main.js]

Головний скрипт знову став таким, яким він був у перших проектах:


// імпорт
import Vue from 'vue'
import App from './App.vue'

// плагіни
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// Bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// конфігурація
Vue.config.productionTip = false

// інстанціювання проєкту [App]
new Vue({
  name: "app",
  render: h => h(App),
}).$mount('#додаток')

14.2. Головний вигляд [App]

Код головного вікна [App] виглядає так:


<template>
  <div class="container">
    <b-card>
      <!-- повідомлення -->
      <b-alert show variant="success" align="center">
        <h4>[vuejs-12] : gestion des tables</h4>
      </b-alert>
      <!-- компонент «Таблиця» -->
      <Table @supprimerLigne="supprimerLigne" :lignes="lignes" @rechargerListe="rechargerListe" />
    </b-card>
  </div>
</template>

<script>
  import Table from "./components/Table";
  export default {
    // назва
    name: "app",
    // використані компоненти
    components: {
      Table
    },
    // внутрішній стан
    data() {
      return {
        // список моделювань
        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 }
        ]
      };
    },

    // методи
    methods: {
      // видалення рядка
      supprimerLigne(index) {
        // eslint-disable-next-line
        console.log("App supprimerLigne", index);
        // видалення рядка у позиції [index]
        this.lignes.splice(index, 1);
      },
      // перезавантаження таблиці рядків
      rechargerListe() {
        // eslint-disable-next-line
        console.log("App rechargerListe");
        // перегенерація списку рядків
        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 }
        ];
      }
    }
  };
</script>

Коментарі

  • головний вигляд відображає компонент [Table] (рядки 9, 15, 21);
  • рядок 9: компонент [Table] приймає параметр [:lignes], який визначає рядки, що мають відображатися в таблиці HTML. Ці рядки визначаються рядками 27–31 коду;
  • рядок 9: компонент [Table] може генерувати дві події:
    • [supprimerLigne]: для видалення рядка, індекс якого вказано (рядок 38);
    • [rechargerListe]: для оновлення списку рядків 27–31. Адже, як ми побачимо, користувач може видалити деякі з відображених рядків;
  • рядки 38–43: метод, відповідальний за обробку події [supprimerLigne]. Він отримує як параметр індекс рядка, який потрібно видалити;
  • рядки 45–54: метод, що відповідає за обробку події [rechargerListe]. Змінюючи атрибут [lignes] у рядку 27, ми викликаємо оновлення компонента [Table] у рядку 9, оскільки він має параметр [:lignes="lignes"];

14.3. Компонент [Table]

Компонент [Table] має такий вигляд:


<template>
  <div>
    <!-- порожній список -->
    <template v-if="lignes.length==0">
      <b-alert show variant="warning">
        <h4>Votre liste de simulations est vide</h4>
      </b-alert>
      <!-- кнопка оновлення-->
      <b-button variant="primary" @click="rechargerListe">Recharger la liste</b-button>
    </template>
    <!-- непорожній список-->
    <template v-if="lignes.length!=0">
      <b-alert show variant="primary" v-if="lignes.length==0">
        <h4>Liste de vos simulations</h4>
      </b-alert>
      <!-- таблиця моделювань -->
      <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 {
    // властивості
    props: {
      lignes: {
        type: Array
      }
    },
    // внутрішній стан
    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" }
        ]
      };
    },
    // методи
    methods: {
      // видалення рядка
      supprimerLigne(index) {
        // eslint-disable-next-line
        console.log("Table supprimerLigne", index);
        // передача інформації батьківському компоненту
        this.$emit("supprimerLigne", index);
      },
      // перезавантаження списку, що відображається
      rechargerListe() {
        // eslint-disable-next-line
        console.log("Table rechargerListe");
        // посилання події до батьківського компонента
        this.$emit("rechargerListe");
      }
    }
  };
</script>

Коментарі

Цей компонент має два стани:

  1. він відображає список у таблиці HTML;
  2. або повідомлення про те, що список, який потрібно відобразити, порожній;

Перший стан відображається, якщо виконується умова [lignes.length!=0] (рядок 12):

Image

Другий стан відображається, якщо виконується умова [lignes.length==0] (рядок 4).

Image

  • [lignes] — це вхідний параметр компонента (рядки 29–33);
  • рядки 4–10: замість введення блоку коду з тегом <div> тут використано тег <template>. Різниця між ними полягає в тому, що тег <template> не вставляється у згенерований код HTML;
  • рядок 9: коли список, що відображається таблицею HTML, порожній, кнопка пропонує його оновити. При натисканні на цю кнопку виконується метод [rechargerListe] із рядків 57–62. Цей метод просто надсилає до батьківського компонента подію [rechargerListe], яка вимагає від батьківського компонента перегенерувати список, що відображається таблицею HTML;
  • рядки 12–22: код, що відображається, коли список, який потрібно відобразити, не є порожнім;
  • рядок 17: тег <b-table> — це тег, який створює таблицю HTML. Тут використовуються такі атрибути:
    • [striped]: колір фону рядків чергується. Для парних рядків використовується один колір, а для непарних — інший. Це покращує читабельність;
    • [hover]: рядок, над яким наводиться курсор миші, змінює колір;
    • [responsive]: розмір таблиці адаптується до екрана, на якому вона відображається;
    • [:items]: масив елементів, що мають відображатися. Тут масив [lignes] передано як параметр компоненту (рядки 30–32);
    • [:fields]: масив, що визначає верстку таблиці HTML (рядки 37–44);
      • кожен елемент масиву [fields] визначає стовпець таблиці HTML;
      • [label]: позначає заголовок стовпця;
      • [key]: позначає вміст стовпця;
  • рядок 38: визначає стовпець 0 таблиці HTML:
    • [#]: — заголовок стовпця;
    • [id]: є її вмістом. Поле [id] з відображеного рядка заповнить стовпець 0;
  • рядок 39: визначає стовпець 1 таблиці HTML:
    • [Marié] — заголовок стовпця;
    • [marié]: це його вміст. Саме поле [marié] з відображеного рядка заповнить стовпець 0;
  • рядок 43: визначає останній стовпець таблиці HTML:
    • стовпець не має заголовка;
    • його вміст визначається полем [action], яке не існує у відображених рядках. Цей ключ згадується у рядку 18 поля [template]. Отже, ключ тут використовується виключно для ідентифікації стовпця;
  • рядки 18–20: цей код слугує для визначення останнього стовпця таблиці HTML, а саме стовпця з ключем [action]:

<template v-slot:cell(action)="row">

Синтаксис [v-slot:cell(action)] позначає стовпець ключа [action]. Цей синтаксис дозволяє визначити стовпець, коли синтаксису таблиці [fields] недостатньо для його опису. У цьому випадку ми хочемо, щоб останній стовпець містив посилання, яке дозволяє видалити рядок із таблиці HTML:

Image

У синтаксисі [<template v-slot:cell(action)="row">] ім’я [row] позначає рядок таблиці. Можна використовувати будь-яке ім’я на свій розсуд. Можна було б написати [<template v-slot:cell(action)="ligne">];

  • рядок 19: кнопка <b-button>, що відображається як посилання [variant=’link’]. Клік на це посилання викликає виконання методу [supprimerLigne(row.index)]. Тут [row] — це ім’я, присвоєне рядку таблиці HTML, рядок 18 коду;
  • рядки 50–55: метод [supprimerLigne];
  • рядок 54: надсилається подія [supprimerLigne] до батьківського компонента разом із номером рядка, який потрібно видалити;
  • рядки 57–62: метод [rechargerListe];
  • рядок 61: надсилається подія [rechargerListe] до батьківського компонента;

14.4. Виконання проекту

Image

Перший відображений вигляд такий:

Image

Після видалення рядка 1 [1] вигляд стає таким:

Image

Після видалення всіх рядків:

Image

Після натискання кнопки [2] знову з’являється список:

Image