ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Vue3 Teleport, Pinia๋ž‘ ์ฐฐ๋–ก๊ถํ•ฉ?!
    Developer 2024. 1. 29. 10:25
    728x90

    ๐Ÿ™‹๐Ÿปโ€โ™‚๏ธ: wrapper ํ•˜์œ„๋กœ ๋ ˆ์ด์–ด ํ˜•ํƒœ๋กœ ๋œ ๋‹ค์–‘ํ•œ ์•Œ๋Ÿฟ์ด ๋–ด์œผ๋ฉด ์ข‹๊ฒ ์–ด์š”.
    ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป: ๋งค ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค ๋ถˆ๋Ÿฌ์™€์„œ ํ•ด์•ผํ•˜๋‚˜..?

    Vue์—๋Š” ์–ด๋””์„œ ๋ถ™์—ฌ๋„ ์›ํ•˜๋Š” ๊ณณ์œผ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” Teleport๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค!!

    ๐ŸŒŸ ์š”์•ฝ

    1. ํ…”๋ ˆํฌํŠธ ๋ ˆ์ด์–ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค.
    2. ๋ ˆ์ด์–ด ๋‚ด ๋ฐ์ดํ„ฐ๋“ค์€ pinia๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
    3. ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— ๋ ˆ์ด์–ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋“ฑ๋กํ•ด๋†“๋Š”๋‹ค.
    4. ํ•„์š”ํ•œ ๊ณณ์—์„œ pinia๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœํ•œ๋‹ค.

    ๐Ÿ˜‹ Vue Teleport ๋งŒ๋“ค๊ธฐ

    ๋จผ์ € ๊ณตํ†ต์œผ๋กœ ์“ฐ์ผ ๋ ˆ์ด์–ด๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

    <div id="popWrapper" class="toast-popup">
      <div id="popContainer" class="popup-box" role="dialog">
        <h2 class="title-popup">{{ title }}</h2>
        <p class="text-popup" v-html="content" />
        <div class="btn-area02">
          <div v-if="btnType === 2" class="btn-unit04">
            <a @click="onCancel?.(), store.closeLayer?.()">
              <strong>{{ cancel }}</strong>
            </a>
          </div>
          <div class="btn-unit01">
            <a @click="onConfirm?.(), store.closeLayer?.()">
              <strong>{{ confirm }}</strong>
            </a>
          </div>
        </div>
      </div>
    </div>

    ์œ„ ๋งˆํฌ์—…์— ์“ฐ์ธ ํ•จ์ˆ˜ ๋ฐ ๋ณ€์ˆ˜๋Š” pinia๋ฅผ ํ†ตํ•ด ์ปจํŠธ๋กคํ•˜๋Š” ๊ฐ’๋“ค์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    ์ด์ œ ์œ„ ๋งˆํฌ์—…์„ <Teleport>์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค.

    <Teleport v-if="isOpen" to="#container"> ... </Teleport>

    to ์†์„ฑ์— ์–ด๋А element์— ๋ถ™์„์ง€ ์ง€์ •์„ ํ•ด์ค๋‹ˆ๋‹ค.

    <script setup>
    import { useLayerStore } from '@/stores/useLayerStore';
    import { storeToRefs } from 'pinia';
    
    const store = useLayerStore();
    
    const {
      isOpen,
      title,
      content,
      btnType,
      confirm,
      cancel,
      onConfirm,
      onCancel,
    } = storeToRefs(store);
    </script>

    storeToRefs๋Š” ๋ฐ˜์‘์„ฑ์„ ์‚ด๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

    ๐Ÿฃ Pinia๋กœ ์ƒํƒœ๊ด€๋ฆฌ ๋งŒ๋“ค๊ธฐ

    stores/useLayerStore.jsํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

    import { defineStore } from "pinia";
    import { computed, ref } from "vue";
    export const useLayerStore = defineStore("layer", () => {
      const state = ref({
        isOpen: false,
        title: "",
        content: "",
        confirm: "ํ™•์ธ",
        cancel: "",
        btnType: 1,
        onConfirm: null,
        onCancel: null,
        typeClass: "toast-popup",
      });
    
      // getter
      const isOpen = computed(() => state.value.isOpen);
      const title = computed(() => state.value.title);
      const content = computed(() => state.value.content);
      const btnType = computed(() => state.value.btnType);
      const confirm = computed(() => state.value.confirm);
      const cancel = computed(() => state.value.cancel);
      const onConfirm = computed(() => state.value.onConfirm);
      const onCancel = computed(() => state.value.onCancel);
      const typeClass = computed(() => state.value.typeClass);
    
      // action
      function openLayer(data) {
        state.value.isOpen = !state.value.isOpen;
        state.value.title = data.title;
        state.value.content = data.content;
        state.value.confirm = data.confirm ?? state.value.confirm;
        state.value.cancel = data.cancel ?? state.value.cancel;
        state.value.btnType = data.btnType || 1;
        state.value.onConfirm = data.onConfirm;
        state.value.onCancel = data.onCancel;
        state.value.typeClass = data.typeClass;
      }
      function closeLayer() {
        state.value.isOpen = false;
      }
    
      return {
        isOpen,
        title,
        content,
        btnType,
        confirm,
        cancel,
        onConfirm,
        onCancel,
        typeClass,
        openLayer,
        closeLayer,
      };
    });

    ์ด์ œ ์–ด๋А ์ปดํฌ๋„ŒํŠธ์—์„œ๋“  openLayerํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ ˆ์ด์–ด๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

    import { useLayerStore } from "@/stores/useLayerStore";
    
    const { openLayer } = useLayerStore();
    
    openLayer({
      title: "์•ˆ๋‚ด",
      content: `๋‚ด์šฉ`,
      btnType: 2,
      confirm: "ํšŒ์›๊ฐ€์ž…",
      onConfirm: () => {
        router.push("/signup");
      },
      cancel: "์ทจ์†Œ",
    });
    728x90
Designed by Tistory.