Skip to content

Instantly share code, notes, and snippets.

@artemsites
Last active July 16, 2024 16:03
Show Gist options
  • Save artemsites/0a545b74955e57056745036696fb7b86 to your computer and use it in GitHub Desktop.
Save artemsites/0a545b74955e57056745036696fb7b86 to your computer and use it in GitHub Desktop.

Обёртка - функционал для всплывающих окон, внутрь передаётся компонент который нужно отобразить там, пример:

<template>
	<button @click="openPopup()">Открыть попап</button>
	
	<PopupContainer v-model="isPopupOpen">
	  <ShareLink></ShareLink>
	</PopupContainer>
</template>

<script setup>
import PopupContainer from "/src/components/PopupContainer.vue"
import { usePopupContainer } from "/src/composables/usePopupContainer.js"

const { isPopupOpen, openPopup, closePopup } = usePopupContainer()
<script>
<template>
<Teleport to="body">
<Transition>
<div v-if="isOpen" class="popup-overlay" @click="closePopup">
<div class="popup-content" @click.stop>
<button class="popup-close" @click="closePopup">
&times;
</button>
<slot></slot>
</div>
</div>
</Transition>
</Teleport>
</template>
<script setup>
import { ref, watch } from "vue"
const props = defineProps({
modelValue: Boolean
})
const emit = defineEmits(["update:modelValue"])
const isOpen = ref(props.modelValue)
watch(
() => props.modelValue,
(newValue) => {
isOpen.value = newValue
}
)
const closePopup = () => {
emit("update:modelValue", false)
}
</script>
<style lang="scss" scoped>
.v-enter-active.popup-overlay,
.v-leave-active.popup-overlay {
transition: opacity 0.3s ease;
}
.v-enter-from.popup-overlay,
.v-leave-to.popup-overlay {
opacity: 0;
}
.v-enter-active .popup-content,
.v-leave-active .popup-content {
transition: transform 0.3s ease;
}
.v-enter-from .popup-content {
transform: scale(0.85);
}
.v-enter-to .popup-content {
// transform: scale(1);
}
.v-leave-from .popup-content {
// transform: scale(1);
}
.v-leave-to .popup-content {
transform: scale(1.4);
}
.popup-overlay {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
background-color: rgba(0, 0, 0, 0.5);
align-items: center;
z-index: 1000;
position: fixed;
top: 0;
left: 0;
}
.popup-content {
position: relative;
}
.popup-close {
display: inline-flex;
background: none;
border: none;
padding: 10px;
cursor: pointer;
transform: translate(10px, -100%);
position: absolute;
top: 0;
right: 0;
}
.ico-close {
width: 23px;
height: 23px;
}
</style>
import { ref } from "vue"
export function usePopupContainer() {
const isPopupOpen = ref(false)
const openPopup = () => {
isPopupOpen.value = true
}
const closePopup = () => {
isPopupOpen.value = false
}
return {
isPopupOpen,
openPopup,
closePopup
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment