Skip to content

17. Проєкт [vuejs-15]: використання плагіна [Vuex]

Проєкт [vuejs-15] продовжує проєкт [vuejs-14], використовуючи реактивний об’єкт [session], згенерований проєктом [Vuex]. Структура проєкту виглядає наступним чином:

Image

17.1. Встановлення залежності [vuex]

Image

17.2. Скрипт [./session.js]

Об’єкт [session] набуває такого вигляду:


// плагін Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);

// сесія є сховищем Vuex
const session = new Vuex.Store({
  state: {
    // таблиця симуляцій
    lignes: []
  },
  mutations: {
    // генерація списку симуляцій
    generateLignes(state) {
      // eslint-disable-next-line no-console
      console.log("mutation generateLignes");
      // ініціалізація [state.lignes]
      state.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 }
        ];
      // eslint-disable-next-line no-console
      console.log(state.lignes);
    },
    // видалення рядка № індекс
    deleteLigne(state, index) {
      // eslint-disable-next-line no-console
      console.log("mutation deleteLigne");
      // видаляємо рядок № [index]
      state.lignes.splice(index, 1);
    }
  }
});
// експорт об'єкта [session]
export default session;

Коментарі

  • рядки 2–4: плагін [Vuex] інтегрується у фреймворк [Vue];
  • рядок 7: сесія стає об’єктом типу [Vuex.Store];
  • рядки 8–11: властивість [state] містить спільний стан додатка [Vue]. Ця властивість буде доступна для всіх компонентів додатка. Тут ми надаємо спільний доступ до масиву симуляцій [lignes] (рядок 10);
  • рядки 12–35: властивість [mutations] об’єднує методи, що змінюють вміст об’єкта [state];
  • рядки 14–26: властивість [generateLignes] — це функція, що генерує початкове значення для властивості [state.lignes]. Вона приймає тут [state] як параметр. Рядки 18–23: властивість [state.lignes] ініціалізується;
  • рядки 28–35: властивість [deleteLigne] — це функція, яка видаляє рядок із масиву [state.lignes]. Її параметрами є:
    • [state], що представляє об’єкт із рядків 8–11;
    • [index] — номер рядка, який потрібно видалити;
  • функції властивості [mutations] завжди приймають як перший параметр об’єкт, що представляє властивість [state] рядка 8. Наступні параметри надаються кодом, що викликає зміну;
  • рядок 37: експортується об’єкт [session].

На відміну від попереднього проєкту [vuejs-13], тут у нас не буде плагіна для надання компонентам доступу до сесії через атрибут [Vue.$session].

17.3. Головний скрипт [./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'

// сесія
import session from './session';

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

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

Коментарі

  • рядок 14: сесія імпортується;
  • рядок 23: вона передається до головного виду в атрибуті з назвою [store] (це обов’язково). Завдяки плагіну [Vuex] цей атрибут стає доступним для всіх компонентів у атрибуті [Vue.$store]. Отже, ми маємо конфігурацію, дуже схожу на ту, що була в попередньому проєкті: там, де в компоненті доступ до сесії здійснювався за допомогою нотації [this.$session], тепер доступ здійснюватиметься за допомогою нотації [this.$store];

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

Головний вигляд [App] змінюється наступним чином:


<template>
  <div class="container">
    <b-card>
      <!-- повідомлення -->
      <b-alert show variant="success" align="center">
        <h4>[vuejs-14] : utilisation du plugin [Vuex]</h4>
      </b-alert>
      <!-- таблиця HTML -->
      <Table />
    </b-card>
  </div>
</template>

<script>
import Table from "./components/Table";
export default {
  // назва
  name: "app",
  // компоненти
  components: {
    Table
  },
  // життєвий цикл
  created() {
    // генерація таблиці симуляцій
    this.$store.commit("generateLignes");
  }
};
</script>

Коментарі

  • рядок 9: представлення [App] використовує компонент [Table], але більше не отримує від нього подій, оскільки магазин [Vuex] є реактивним;
  • рядки 24–27: метод [created] виконується одразу після створення компонента [App]. У ньому виконується мутація з назвою [generateLignes], яка генерує початкове значення для масиву симуляцій. Зверніть увагу на особливий синтаксис цієї інструкції. Нагадаємо, що позначення [this.$store] посилається на властивість [store] подання, інстанційованого в [main.js]:

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

Отже, позначення [this.$store] позначає об’єкт [session]. Далі записуємо [this.$store.commit("generateLignes")], щоб виконати мутацію з назвою [generateLignes]. Ця мутація є функцією;

17.5. Компонент [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 {
  // розрахований стан
  computed: {
    lignes() {
      return this.$store.state.lignes;
    }
  },
  // внутрішній стан
  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.$store.commit("deleteLigne", index);
    },
    // перезавантаження списку, що відображається
    rechargerListe() {
      // eslint-disable-next-line
      console.log("Table rechargerListe");
      // перегенерувати список симуляцій
      this.$store.commit("generateLignes");
    }
  }
};
</script>

Коментарі

  • [template] у рядках 1–24 не змінюється;
  • рядки 30–32: обчислювана властивість [lignes] тепер використовує [store] з [Vuex];
  • рядки 49–54: для видалення рядка з таблиці HTML використовується мутація [deleteLigne], отримана з [store], що походить від [Vuex]. Як параметр передається номер [index] рядка, який потрібно видалити (рядок 53);
  • рядки 56–61: щоб перезавантажити таблицю HTML з новим списком, використовується мутація [generateLignes] з [store], яка походить від [Vuex];

17.6. Conclusion

Атрибути [Vue.$session] проекту [vuejs-13] та [Vue.$store] проекту [vuejs-15] дуже схожі між собою. Вони мають одну й ту саму мету: обмін інформацією між поданнями. Перевага об’єкта [store] полягає в тому, що він є інтерактивним, тоді як об’єкт [session] таким не є. Однак проект [vuejs-14] продемонстрував, що об’єкт [session] легко зробити реактивним, дублюючи його у реактивних властивостях переглядів.