- vừa được xem lúc

Teleport trong vue 3

0 0 5

Người đăng: FFF

Theo Viblo Asia

Bài viết này giới thiệu Teleport vue 3 và cùng là một chức năng modal đơn giản ✌️

Teleport trong vue 3 là gì?

  • <Teleport> là một thành phần tích hợp sẵn trong Vue 3 cho phép chúng ta "teleport" (chuyển đổi vị trí) một phần của template của một thành phần vào một nút DOM tồn tại ngoài cấu trúc DOM của thành phần đó.
  • Nó có một prop : to và một default slot hiển thị nội dung vị trí sẽ hiển thị trong phần tử DOM được đề cập ở prop to.
  • Disabling Teleport : dùng prop disabled
<Teleport :disabled="true"> ...
</Teleport>

Example:

  • Ví dụ làm một modal được viết băng vue 3, ts, tailwind
<script setup lang="ts">
import { ref } from 'vue';
import CloseIcon from '@/components/icons/CloseIcon.vue';
import { useOnClickOutside } from '@/composable/click-outside'; type TProps = { show: boolean; title: string; textSubmit?: string; clickToClose?: boolean;
}; const props = withDefaults(defineProps<TProps>(), { clickToClose: false
}); // cú pháp trong vue 3.3
const emit = defineEmits<{ onSubmit: []; onClose: [];
}>(); const modalRef = ref<HTMLElement | null>(null); useOnClickOutside(modalRef, () => { if (!props.clickToClose) return; emit('onClose');
});
</script> <template> <Teleport to="body"> <transition name="fade"> <div v-if="show"> <div class="fixed inset-0 bg-black opacity-30 cursor-pointer" /> <div class="fixed inset-0 flex items-center justify-center z-[999]"> <div ref="modalRef" class="bg-white border-gray-200 w-[342px] md:w-[500px] lg:w-[640px] rounded-lg relative" > <CloseIcon class="absolute top-[27.5px] right-6 hover:cursor-pointer z-10" @click="emit('onClose')" /> <div class="divide-y divide-gray-200"> <div class="p-6 text-[#111928] text-lg leading-[27px] font-semibold" > <p>{{ title }}</p> </div> <div class="p-6"> <slot name="content" /> </div> // check dùng cho modal ko cần nút bấm <div v-if="!!textSubmit" class="p-6 flex justify-center"> <button @click="emit('onSubmit')" class="bg-[#1C64F2] px-4 py-2.5 rounded-lg text-white text-sm font-medium leading-[21px]" > {{ textSubmit }} </button> </div> </div> </div> </div> </div> </transition> </Teleport>
</template> 
  • Phần <script setup>: Đây là một tính năng mới trong Vue 3 cho phép bạn viết logic component mà không cần phải khai báo các biến và hàm bằng cách sử dụng các khai báo ngắn gọn như ref, defineProps, và defineEmits.

  • Import: Dòng import { ref } from 'vue'; import ref từ thư viện Vue để tạo một ref cho phần tử modal.

  • Import CloseIcon : import thành phần CloseIcon file svg nút đóng modal.

  • Import useOnClickOutside hàm useOnClickOutside từ một composable (composable là một cách tái sử dụng logic trong Vue) được định nghĩa trong file click-outside.ts. Chức năng này cho phép chúng ta xử lý sự kiện nhấp chuột bên ngoài phần tử modal.

import type { Ref } from 'vue';
import { useEventListener } from './use-event-listener'; export function useOnClickOutside( rootEl: Ref<HTMLElement | null>, callback: () => any
) { // `mousedown` or `mouseup` here makes it easier to not trigger the callback immedialty // if you want to use `click` you need to call `stopPropagation` on the trigger element. useEventListener(window, 'mouseup', (e: Event) => { const clickedEl = e.target as HTMLElement; // skip if the root element contains the clicked element if (rootEl.value?.contains(clickedEl)) { return; } // otherwise execute the action callback(); });
} // import { onMounted, onBeforeUnmount } from 'vue'; // use-event-listener.ts
export function useEventListener( target: EventTarget, event: string, handler: (e: Event) => any
) { onMounted(() => { target.addEventListener(event, handler); }); // clean it up onBeforeUnmount(() => { target.removeEventListener(event, handler); });
}

Mình đã có giới thiệu một số composable hay dùng ở đây

  • Define Props: Dòng type TProps = { ... }; định nghĩa một kiểu cho các props nhận vào thành phần modal. Props bao gồm show (kiểm soát hiển thị modal), title (tiêu đề modal), textSubmit (văn bản nút submit), và clickToClose (có cho phép đóng modal khi nhấp chuột bên ngoài hay không).

  • Define Default Props: sử dụng defineProps để định nghĩa các props và withDefaults để thiết lập các giá trị mặc định cho các props nếu không được cung cấp.

  • Define Emits: sử dụng defineEmits để định nghĩa các sự kiện mà thành phần này có thể phát ra, trong trường hợp này là onSubmit và onClose.

  • Modal Ref: const modalRef = ref<HTMLElement | null>(null); tạo một ref cho phần tử modal, sẽ được sử dụng trong useOnClickOutside để xác định phần tử bên ngoài modal khi nhấp chuột.

  • useOnClickOutside(modalRef, () => { ... }); sử dụng composable useOnClickOutside để xử lý sự kiện nhấp chuột bên ngoài phần tử modal. Khi nhấp chuột bên ngoài và clickToClose được bật, sự kiện onClose sẽ được phát ra.

Sử dụng:

 <script setup lang="ts"> // import RootModal from '' </script> <template> <RootModal :show="isShow" :title="''Nhap title" :text-submit="'text ......'" @on-close="emit('onClose')" @on-submit="emit('onSubmit')" > <template #content> // nội dung </template> </RootModal>
</template>

** TRÊN ĐÂY LÀ NHỮNG CHIA SẺ CỦA MÌNH, CẢM ƠN CÁC BẠN ĐÃ ĐỌC BÀI VIẾT .**😘

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tôi đã tạo một custom hook trong Vue 3 thế nào?

Xin chào mọi nguời , mình là một coder vô danh kinh nghiệm chưa nhiều lần đầu viết bài nên bố cục , từ ngữ, kiến thức có chỗ chưa được đúng mong mọi người góp ý nhẹ tay ạ. . . .

0 0 228

- vừa được xem lúc

Vue 3 - Hướng dẫn & Ví dụ về Đăng nhập Facebook (Part 1)

I. Giới thiệu.

0 0 23

- vừa được xem lúc

Vue 3 Let's start - Từng bước làm chủ Vue Js

Video được đăng tại channel SUNTECH VIỆT NAM

0 0 27

- vừa được xem lúc

[Vue3] Tích hợp Vue I18n đơn giản, siêu nhẹ cho các dự án Vue3

Tại sao mình quyết định viết một plugin i18n cho dự án mới. . Lightweight. Chỉ có các feature thật sự cần thiết.

0 0 31

- vừa được xem lúc

Giới thiệu Composition API trong Vue3 - Vuejs

Tổng quan. Vuejs là một trong những Javascript Framework hot nhất hiện nay.

0 0 922

- vừa được xem lúc

Cài đặt ESLint + Prettier cho Nuxt 3

Cho tới thời điểm publish bài viết, phần document setup ESLint trên trang https://v3.nuxtjs.org chưa đầy đủ. Bài viết này note lại cách setup ESLint + Prettier cho Nuxt.

0 0 11