Khám phá 10 Composables Quan trọng trong Vue.js cho Dự án Của Bạn

Trong dự án Vue.js, composables là các hàm dùng để tái sử dụng logic và trạng thái giữa các component khác nhau. Dưới đây là một số Vue.js composables phổ biến mà bạn có thể sử dụng trong dự án của mình:

useLocalStorage và useSessionStorage

Các composables này giúp bạn lưu trữ và quản lý dữ liệu vào local storage hoặc session storage của trình duyệt.

<template>
  <div>
    <p>Last visited: {{ lastVisited }}</p>
  </div>
</template>

<script>
import { useLocalStorage } from '@vueuse/core';

export default {
  setup() {
    const lastVisited = useLocalStorage('last_visited', new Date());

    return {
      lastVisited,
    };
  },
};
</script>

useDebounce và useThrottle

Các composables này giúp bạn áp dụng debounce (trì hoãn) hoặc throttle (điều tiết) cho các hàm xử lý sự kiện, giúp kiểm soát tần suất thực hiện hành động.

<template>
  <div>
    <input v-model="searchQuery" @input="handleSearch" />
    <p>Search results: {{ searchResults }}</p>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useDebounce } from '@vueuse/core';

export default {
  setup() {
    const searchQuery = ref('');
    const searchResults = ref([]);

    const handleSearch = useDebounce(() => {
      // Thực hiện tìm kiếm dựa trên searchQuery
      // Cập nhật searchResults
    }, 300);

    return {
      searchQuery,
      searchResults,
      handleSearch,
    };
  },
};
</script>

useMediaQueries

Composable này giúp bạn theo dõi các media query để thực hiện các hành động phản ứng dựa trên kích thước màn hình.

<template>
  <div>
    <p>Current screen size: {{ screenSize }}</p>
  </div>
</template>

<script>
import { useMediaQueries } from '@vueuse/core';

export default {
  setup() {
    const { screenSize } = useMediaQueries({
      mobile: 'screen and (max-width: 640px)',
      tablet: 'screen and (max-width: 1024px)',
      desktop: 'screen and (min-width: 1025px)',
    });

    return {
      screenSize,
    };
  },
};
</script>

useAsync

Composable này giúp bạn quản lý các tác vụ bất đồng bộ và theo dõi trạng thái của chúng (đang xử lý, thành công, lỗi).

<template>
  <div>
    <button @click="fetchData">Fetch Data</button>
    <p v-if="status === 'pending'">Loading...</p>
    <p v-if="status === 'success'">Data loaded: {{ data }}</p>
    <p v-if="status === 'error'">Error loading data.</p>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useAsync } from '@vueuse/core';

export default {
  setup() {
    const fetchData = async () => {
      // Giả lập việc tải dữ liệu
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
      return data;
    };

    const { execute, value: data, status } = useAsync(fetchData);

    return {
      fetchData: execute,
      data,
      status,
    };
  },
};
</script>

useEventListener

Composable này giúp bạn theo dõi sự kiện trên phần tử DOM và thực hiện các hành động tương ứng.

<template>
  <div>
    <p>Mouse position: {{ mouseX }}, {{ mouseY }}</p>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useEventListener } from '@vueuse/core';

export default {
  setup() {
    const mouseX = ref(0);
    const mouseY = ref(0);

    useEventListener('mousemove', (event) => {
      mouseX.value = event.clientX;
      mouseY.value = event.clientY;
    });

    return {
      mouseX,
      mouseY,
    };
  },
};
</script>

useRouter

Composable này giúp bạn truy cập thông tin về router và các tham số của URL trong ứng dụng Vue Router.

<template>
  <div>
    <p>Current route: {{ currentRoute }}</p>
  </div>
</template>

<script>
import { useRoute } from 'vue-router';

export default {
  setup() {
    const route = useRoute();
    const currentRoute = route.fullPath;

    return {
      currentRoute,
    };
  },
};
</script>

usePagination

Composable này giúp bạn quản lý việc hiển thị dữ liệu trang theo trang và thao tác điều hướng.

<template>
  <div>
    <ul>
      <li v-for="item in currentPageData" :key="item.id">{{ item.name }}</li>
    </ul>
    <button @click="previousPage" :disabled="currentPage === 1">Previous</button>
    <button @click="nextPage" :disabled="currentPage === totalPages">Next</button>
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import { usePagination } from '@vueuse/core';

export default {
  setup() {
    const data = ref([...]); // Dữ liệu trang
    const itemsPerPage = 10;
    const currentPage = ref(1);

    const { currentPageData, nextPage, previousPage, totalPages } = usePagination(data, itemsPerPage, currentPage);

    return {
      currentPageData,
      nextPage,
      previousPage,
      currentPage,
      totalPages,
    };
  },
};
</script>

useIntersectionObserver

Composable này giúp bạn theo dõi sự kiện giao nhau của phần tử với viewport, rất hữu ích cho việc thực hiện hành động khi phần tử xuất hiện hoặc biến mất.

<template>
  <div>
    <div ref="observedElement">Observed Element</div>
    <p v-if="isIntersecting">Element is intersecting!</p>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useIntersectionObserver } from '@vueuse/core';

export default {
  setup() {
    const observedElement = ref(null);
    const { isIntersecting } = useIntersectionObserver(observedElement, {});

    return {
      observedElement,
      isIntersecting,
    };
  },
};
</script>

useClipboard

Composable này giúp bạn sao chép dữ liệu vào clipboard và quản lý trạng thái của thao tác sao chép.

<template>
  <div>
    <p>Text to copy: {{ textToCopy }}</p>
    <button @click="copyText">Copy Text</button>
    <p v-if="copied">Copied to clipboard!</p>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useClipboard } from '@vueuse/core';

export default {
  setup() {
    const textToCopy = ref('Hello, Vue.js!');
    const { copy, copied } = useClipboard();

    const copyText = () => {
      copy(textToCopy.value);
    };

    return {
      textToCopy,
      copyText,
      copied,
    };
  },
};
</script>

useRouteQuery

Composable này giúp bạn quản lý trạng thái truy vấn URL và cập nhật nội dung trang dựa trên truy vấn URL.

<template>
  <div>
    <input v-model="searchQuery" />
    <button @click="updateQuery">Search</button>
    <p>Search results: {{ searchResults }}</p>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useRouter, useRouteQuery } from '@vueuse/core';

export default {
  setup() {
    const router = useRouter();
    const searchQuery = ref('');
    const { search } = useRouteQuery();
    const searchResults = ref([]);

    const updateQuery = () => {
      router.push({ query: { search: searchQuery.value } });
      // Thực hiện tìm kiếm dựa trên searchQuery và cập nhật searchResults
    };

    return {
      searchQuery,
      searchResults,
      updateQuery,
    };
  },
};
</script>

Nhớ rằng, để sử dụng các composables này, bạn cần cài đặt thư viện @vueuse/core bằng cách sử dụng npm hoặc yarn. Các composables này giúp bạn tái sử dụng logic và trạng thái phổ biến trong dự án Vue.js của bạn, giúp tối ưu hóa quá trình phát triển và quản lý mã nguồn.