From 5a91cd264ff5b4c754acf5d969181f7ee8fe429f Mon Sep 17 00:00:00 2001 From: robonen Date: Sat, 5 Oct 2024 17:56:22 +0700 Subject: [PATCH] feat(packages/vue): add useMounted composable --- .../src/composables/useMounted/index.test.ts | 27 +++++++++++++++++++ .../vue/src/composables/useMounted/index.ts | 25 +++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 packages/vue/src/composables/useMounted/index.test.ts create mode 100644 packages/vue/src/composables/useMounted/index.ts diff --git a/packages/vue/src/composables/useMounted/index.test.ts b/packages/vue/src/composables/useMounted/index.test.ts new file mode 100644 index 0000000..da2adb0 --- /dev/null +++ b/packages/vue/src/composables/useMounted/index.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from 'vitest'; +import { defineComponent, nextTick, ref } from 'vue'; +import { mount } from '@vue/test-utils' +import { useMounted } from '.'; + +const ComponentStub = defineComponent({ + setup() { + const isMounted = useMounted(); + + return { isMounted }; + }, + template: `
{{ isMounted }}
`, +}); + +describe('useMounted', () => { + it('return the mounted state of the component', async () => { + const component = mount(ComponentStub); + + // Initial render + expect(component.text()).toBe('false'); + + await nextTick(); + + // Will trigger a render + expect(component.text()).toBe('true'); + }); +}); diff --git a/packages/vue/src/composables/useMounted/index.ts b/packages/vue/src/composables/useMounted/index.ts new file mode 100644 index 0000000..16ea4f5 --- /dev/null +++ b/packages/vue/src/composables/useMounted/index.ts @@ -0,0 +1,25 @@ +import { onMounted, readonly, ref, type ComponentInternalInstance } from 'vue'; +import { getLifeCycleTarger } from '../../utils'; + +/** + * @name useMounted + * @category Components + * @description Returns a ref that tracks the mounted state of the component (doesn't track the unmounted state) + * + * @param {ComponentInternalInstance} [instance] The component instance to track the mounted state for + * @returns {Readonly>} The mounted state of the component + * + * @example + * const isMounted = useMounted(); + * + * @example + * const isMounted = useMounted(getCurrentInstance()); + */ +export function useMounted(instance?: ComponentInternalInstance) { + const isMounted = ref(false); + const targetInstance = getLifeCycleTarger(instance); + + onMounted(() => isMounted.value = true, targetInstance); + + return readonly(isMounted); +}