diff --git a/packages/core/useMediaQuery/index.ts b/packages/core/useMediaQuery/index.ts index e1c92de5711..1c8a172c914 100644 --- a/packages/core/useMediaQuery/index.ts +++ b/packages/core/useMediaQuery/index.ts @@ -1,7 +1,8 @@ /* this implementation is original ported from https://github.com/logaretm/vue-use-web by Abdelrahman Awad */ -import { ref } from 'vue-demi' -import { tryOnBeforeMount, tryOnScopeDispose } from '@vueuse/shared' +import { ref, watchEffect } from 'vue-demi' +import type { MaybeComputedRef } from '@vueuse/shared' +import { resolveRef, tryOnScopeDispose } from '@vueuse/shared' import type { ConfigurableWindow } from '../_configurable' import { defaultWindow } from '../_configurable' import { useSupported } from '../useSupported' @@ -13,40 +14,43 @@ import { useSupported } from '../useSupported' * @param query * @param options */ -export function useMediaQuery(query: string, options: ConfigurableWindow = {}) { +export function useMediaQuery(query: MaybeComputedRef, options: ConfigurableWindow = {}) { const { window = defaultWindow } = options - const isSupported = useSupported(() => window && 'matchMedia' in window && typeof window!.matchMedia === 'function') + const isSupported = useSupported(() => window && 'matchMedia' in window && typeof window.matchMedia === 'function') let mediaQuery: MediaQueryList | undefined const matches = ref(false) + const cleanup = () => { + if (!mediaQuery) + return + if ('removeEventListener' in mediaQuery) + // eslint-disable-next-line @typescript-eslint/no-use-before-define + mediaQuery.removeEventListener('change', update) + else + // @ts-expect-error deprecated API + // eslint-disable-next-line @typescript-eslint/no-use-before-define + mediaQuery.removeListener(update) + } + const update = () => { if (!isSupported.value) return - if (!mediaQuery) - mediaQuery = window!.matchMedia(query) - matches.value = mediaQuery.matches - } - tryOnBeforeMount(() => { - update() + cleanup() - if (!mediaQuery) - return + mediaQuery = window!.matchMedia(resolveRef(query).value) + matches.value = mediaQuery.matches if ('addEventListener' in mediaQuery) mediaQuery.addEventListener('change', update) else // @ts-expect-error deprecated API mediaQuery.addListener(update) + } + watchEffect(update) - tryOnScopeDispose(() => { - if ('removeEventListener' in mediaQuery!) - mediaQuery!.removeEventListener('change', update) - else - mediaQuery!.removeListener(update) - }) - }) + tryOnScopeDispose(() => cleanup()) return matches }