-
Vue3 Teleport, Pinia๋ ์ฐฐ๋ก๊ถํฉ?!Developer 2024. 1. 29. 10:25728x90
๐๐ปโโ๏ธ: wrapper ํ์๋ก ๋ ์ด์ด ํํ๋ก ๋ ๋ค์ํ ์๋ฟ์ด ๋ด์ผ๋ฉด ์ข๊ฒ ์ด์.
๐จ๐ปโ๐ป: ๋งค ์ปดํฌ๋ํธ๋ง๋ค ๋ถ๋ฌ์์ ํด์ผํ๋..?Vue์๋ ์ด๋์ ๋ถ์ฌ๋ ์ํ๋ ๊ณณ์ผ๋ก ๋ณด๋ผ ์ ์๋
Teleport
๊ฐ ์์ต๋๋ค!!๐ ์์ฝ
- ํ ๋ ํฌํธ ๋ ์ด์ด ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ ๋ค.
- ๋ ์ด์ด ๋ด ๋ฐ์ดํฐ๋ค์ pinia๋ก ๊ด๋ฆฌํ๋ค.
- ์ต์์ ์ปดํฌ๋ํธ์ ๋ ์ด์ด ์ปดํฌ๋ํธ๋ฅผ ๋ฑ๋กํด๋๋๋ค.
- ํ์ํ ๊ณณ์์ 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'Developer' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ์ฆ WebHook์ผ๋ก ์๋ฌ ์๋ฆผ๋ฐ๊ธฐ (0) 2024.02.02 git actions๋ก ssh ์ ์ํ์ฌ ์๋ ๋ฐฐํฌ ํ๊ธฐ (2) 2024.02.01 web push, ์ด๋ ๊ฒ ์ฌ์ด๊ฑฐ์์ด? (2) 2024.01.29 Placeholder ์ค๋ฐ๊ฟ ์ ์ฉํ๊ธฐ (0) 2024.01.26 MAC nginx ์ค์นํ๊ธฐ (0) 2024.01.14