# useMediaQuery

## 使用方法

SSR 安全的媒体查询 hook，订阅 `window.matchMedia` 的变化，返回这条媒体查询当前是否匹配。只要 `matchMedia` 存在，第一次的值在 setup 阶段就读出来了，所以布局判断不用等到挂载；服务端上这个 ref 从 `false` 开始。组件存活期间会跟着变化走，卸载时摘掉监听。

查询字符串是一段普通字符串，每次调用只读一次。要跟着一个会变的查询走，就在那个值所在的地方重新调用一次 hook。

```ts
import { useMediaQuery } from '@astryx-vue/core'
```

## 建议

| 指引 | 实践 |
| --- | --- |
| 推荐 | 用来做响应式的布局切换：视口宽度、深浅色偏好、动效偏好。 |
| 推荐 | 能用 Astryx 的响应式 token 和组件属性时，优先用它们，别手写断点逻辑。 |
| 避免 | 用在服务端渲染、且首屏必须对得上的内容上；服务端上它永远返回 false。 |

## 示例

### useMediaQuery — 自适应呈现

媒体查询是产品策略，呈现方式仍然是压在它上面的一层确定性覆盖：hook 只回答「是不是触摸取向的那一档」。

```vue
<script setup lang="ts">
import { useMediaQuery } from '@astryx-vue/core'
import { SegmentedControl, SegmentedControlItem } from '@astryx-vue/core/SegmentedControl'
import { Text } from '@astryx-vue/core/Text'
import { computed, ref } from 'vue'

// Product policy: bottom sheet only on a narrow screen with no hover and a coarse pointer.
const TOUCH_RANGE = '(max-width: 1024px) and (pointer: coarse) and (hover: none)'

const isTouchRange = useMediaQuery(TOUCH_RANGE)
const override = ref<'auto' | 'dialog' | 'bottom-sheet'>('auto')

const presentation = computed(() => {
  if (override.value !== 'auto')
    return override.value
  return isTouchRange.value ? 'bottom-sheet' : 'dialog'
})
</script>

<template>
  <div class="media-query-preview">
    <Text type="supporting" color="secondary">
      {{ TOUCH_RANGE }}
    </Text>
    <code class="media-query-preview__value">
      matches: {{ isTouchRange }}
    </code>
    <SegmentedControl v-model="override" label="Presentation override">
      <SegmentedControlItem label="Auto" value="auto" />
      <SegmentedControlItem label="Dialog" value="dialog" />
      <SegmentedControlItem label="Bottom sheet" value="bottom-sheet" />
    </SegmentedControl>
    <Text type="body">
      Presentation: {{ presentation }}
    </Text>
  </div>
</template>

<style scoped>
.media-query-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.media-query-preview__value {
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--astryx-color-background-muted);
  font-family: var(--astryx-font-family-code, ui-monospace, monospace);
  font-size: 0.75rem;
  color: var(--astryx-color-text-secondary);
}
</style>
```

## 参数

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `query` | `string` | — | 要判断的 CSS 媒体查询字符串，例如 `'(max-width: 640px)'`。每次调用只读一次，请传固定的字符串。必填。 |

## 返回值

| 名称 | 类型 | 说明 |
| --- | --- | --- |
| `matches` | `Ref<boolean>` | 这条媒体查询当前是否匹配。客户端在 setup 阶段读一次，服务端上是 `false`。 |
