image
https://unsplash.com/photos/R4y_E5ZQDPg

W tym wpisie pokażę pewien prosty wzorzec, który można wykorzystać m.in. do stworzenia elastycznego modal box'a.

Wykorzystując dotychczas zdobytą wiedzę o komponentach i Vue routerze, zbudujemy modal box wyświetlający dowolny komponent w oparciu o informacje z routera. Zachęcam do zobaczenia poprzednego wpisu w którym opisuję podstawy Vue routera od strony teoretycznej.

W pierwszym kroku stwórzmy komponent modal.vue, który zostanie wrapperem dla wyświetlanych komponentów. Komponent modal "otrzyma" z Vue routera informację jaki komponent wyrenderować.

<template>
  <transition name="fade">
    <div class="c-modal-outer">
      <div class="c-modal-background" @click="close"></div>
      <transition name="fade-modal" appear>
        <div class="c-modal">
          <div class="c-modal__inner">
            <button class="btn-close" @click="close">&times;</button>
            <component :is="content" v-bind="contentProps"></component>
          </div>
        </div>
      </transition>
    </div>
  </transition>
</template>

<script>
  export default {
    name: 'modal',
    props: ['content', 'contentProps'],
    methods: {
      close() {
        this.$router.go(-1);
      }
    }
  };
</script>
<style>
  ...;
</style>

Oprócz wyświetlenia modal boxa, dzieje się tu jedna ciekawa rzecz, czyli dynamiczne wstawienie komponentu przekazanego przez obiekt props. Poniższa linia odpowiada za jego zamontowanie oraz zbindowanie dodatkowych propsów.

<component :is="content" v-bind="contentProps"></component>

Spójrzmy na konfigurację routera z poprzedniego wpisu.

 {
      path: '/login',
      name: 'login',
      components: {
        default: HelloWorld,
        modal: Modal
      },
      props: {
        modal: () => ({ content: Login })
      }
    },

Jako propsy dla modala przekazywana jest funkcja, która zwraca obiekt z przypisaną referencją do komponentu, który ma zostać wstawiony do modala.

Zatem wywołanie ścieżki /login powinno zakończyć się otworzeniem modala, na tle komponentu HelloWorld oraz wstawić komponent Login w jego "środek".

Taka konstrukcja umożliwia nam budowanie kolejnych modal boxów ze zmienną treścią w opaciu o ścieżki routera.

Podsumowanie

Przedstawione rozwiązanie się dobrze skaluje, ale ma 2 małe wady:

  • plik routera puchnie, w miarę kolejnych wariantów modal boxa,
  • ponieważ ten pattern zakłada, że router steruje wyświetleniem każdego elementu, zdaża się, ze modal z ta samą zawartością, ale na różnych ścieżkach, trzeba zdefiniować kilka razy, aby zachować spójność widoków.