在 TypeScript 中使用useQuasar()获取$q实例完全指南
在 TypeScript 中使用useQuasar()获取$q实例完全指南
概述
$q是 Quasar 框架提供的全局对象,集成了通知(notify)、对话框(dialog)、加载条(loading)、屏幕尺寸信息(screen)等核心功能。useQuasar()是 Vue Composables API,用于在 Vue 组件中获取$q实例。本文档详细介绍在不同.ts文件场景下获取$q的方法、示例及注意事项,确保企业级项目中高效、规范地使用 Quasar 功能。
一、使用场景与核心方法概览
根据文件类型和执行上下文,$q实例的获取方式分为以下场景:
|
使用场景 |
推荐方法 |
核心逻辑 |
|
Vue 组件(<script setup>/setup()) |
直接调用useQuasar() |
利用 Vue Composables 上下文,在组件初始化时获取实例 |
|
外部纯.ts文件(工具/服务) |
依赖注入(传递$q实例) |
从组件或应用入口传入$q,避免直接在非 Vue 上下文中调用useQuasar() |
|
Quasar Boot 文件(应用启动脚本) |
通过Boot函数参数访问app实例 |
从app.config.globalProperties中获取全局$q |
|
需增强 TypeScript 类型提示 |
扩展 Vue 全局属性接口 |
声明ComponentCustomProperties,使$q类型在全项目生效 |
二、分场景实现方法
2.1 场景一:在 Vue 组件或 Composables 中使用(推荐)
适用范围:Vue 单文件组件(.vue)、自定义 Composables(.ts,需在组件上下文中调用)。
原理:useQuasar()是 Vue Composables,需在 Vue 的setup()生命周期或<script setup>中执行,此时能获取到 Vue 实例上下文。
示例 1:Composition API 组件(<script setup>)
<!-- src/components/MyComponent.vue -->
<script setup lang="ts">
import { useQuasar } from 'quasar'
// 直接调用 useQuasar() 获取 $q 实例(必须在 <script setup> 或 setup() 中)
const $q = useQuasar()
// 使用 $q 功能示例
const showNotification = () => {
$q.notify({
type: 'positive',
message: '操作成功!',
position: 'top'
})
}
const checkScreenSize = () => {
// 访问屏幕尺寸信息
if ($q.screen.lt.md) { // 小于中等屏幕尺寸(< 960px)
console.log('当前为移动设备视图')
}
}
</script>
<template>
<q-btn @click="showNotification" label="显示通知" />
</template>
示例 2:Options API 组件(含setup()函数)
// src/components/OptionsApiComponent.ts
import { useQuasar } from 'quasar'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'OptionsApiComponent',
setup() {
// 在 setup() 函数中调用 useQuasar()
const $q = useQuasar()
// 可通过 return 将 $q 暴露给模板或组件其他方法
return { $q }
},
methods: {
showDialog() {
// 在组件方法中使用 $q(需先在 setup() 中 return)
this.$q.dialog({
title: '提示',
message: '这是通过 Options API 调用的对话框'
})
}
}
})
2.2 场景二:在外部纯.ts文件中使用(工具/服务类)
适用范围:独立工具函数(@/utils/)、API 服务(@/services/)等非 Vue 组件文件。
痛点:直接在纯.ts文件中调用useQuasar()会报错(缺少 Vue 上下文)。
解决方案:通过依赖注入将$q实例从组件/应用入口传递给外部文件,或创建全局$q实例管理工具。
方法 A:依赖注入(推荐,显式传递)
1. 在 Vue 组件中获取$q并传入外部函数:
// src/components/MyComponent.vue (script setup 部分)
import { useQuasar } from 'quasar'
import { handleApiError } from '@/utils/api-utils' // 导入外部工具函数
const $q = useQuasar()
// 调用外部函数时,将 $q 作为参数传入
const fetchData = async () => {
try {
await api.getData()
} catch (error) {
handleApiError(error, $q) // 传递 $q 实例
}
}
2. 外部.ts文件接收并使用$q:
// src/utils/api-utils.ts
import { QVueGlobals } from 'quasar' // 导入 $q 类型定义
// 函数参数声明 $q 类型,确保类型安全
export function handleApiError(error: unknown, $q: QVueGlobals) {
const errorMsg = error instanceof Error ? error.message : '未知错误'
// 使用传入的 $q 实例显示通知
$q.notify({
type: 'negative',
message: `请求失败: ${errorMsg}`,
timeout: 3000
})
}
方法 B:全局$q实例管理工具(适合频繁使用场景)
创建专用工具文件统一管理$q实例,避免重复传递。
1. 创建实例管理工具:
// src/utils/quasar-instance.ts
import { QVueGlobals } from 'quasar'
// 声明全局变量存储 $q 实例
let $qInstance: QVueGlobals | null = null
// 应用初始化时调用,设置 $q 实例
export function setQuasarInstance(instance: QVueGlobals): void {
$qInstance = instance
}
// 获取 $q 实例(确保已初始化)
export function getQuasarInstance(): QVueGlobals {
if (!$qInstance) {
throw new Error('$q 实例未初始化!请在应用入口调用 setQuasarInstance()')
}
return $qInstance
}
2. 在应用入口初始化$q:
<!-- src/App.vue (应用根组件) -->
<script setup lang="ts">
import { useQuasar } from 'quasar'
import { setQuasarInstance } from '@/utils/quasar-instance'
// 获取 $q 并设置到全局工具中
const $q = useQuasar()
setQuasarInstance($q)
</script>
<template>
<router-view /> <!-- 应用路由出口 -->
</template>
3. 在外部.ts文件中直接使用:
// src/services/user-service.ts
import { getQuasarInstance } from '@/utils/quasar-instance'
export async function deleteUser(id: number): Promise<void> {
const $q = getQuasarInstance() // 直接获取全局 $q 实例
try {
await api.delete(`/users/${id}`)
$q.notify({ type: 'positive', message: '用户删除成功' })
} catch (error) {
$q.notify({ type: 'negative', message: '删除失败,请重试' })
}
}
2.3 场景三:在 Quasar Boot 文件中使用(应用启动脚本)
适用范围:Quasar Boot 文件(src/boot/),用于应用启动时初始化全局配置(如路由守卫、API 拦截器)。
原理:Boot 文件通过Boot函数参数提供app实例,可从app.config.globalProperties中获取全局$q。
步骤与示例
1. 创建 Boot 文件:
// src/boot/init-api.ts
import { Boot } from 'quasar/wrappers'
import axios from 'axios'
// Boot 函数接收包含 app 实例的上下文对象
export default Boot(({ app }) => {
// 从 app 全局属性中获取 $q 实例(注意:Boot 文件中不可直接调用 useQuasar())
const $q = app.config.globalProperties.$q
// 示例:配置 axios 拦截器,使用 $q 显示加载状态
axios.interceptors.request.use(config => {
$q.loading.show({ message: '加载中...' }) // 显示加载条
return config
})
axios.interceptors.response.use(
response => {
$q.loading.hide() // 隐藏加载条
return response
},
error => {
$q.loading.hide()
$q.notify({ type: 'negative', message: '请求失败' }) // 显示错误通知
return Promise.reject(error)
}
)
})
2. 在quasar.conf.js中注册 Boot 文件:
// quasar.conf.js
module.exports = function (ctx) {
return {
boot: [
'init-api' // 注册刚才创建的 Boot 文件
],
// ...其他配置
}
}
2.4 场景四:增强 TypeScript 类型支持
问题:默认情况下,TypeScript 可能无法识别$q的类型,导致编辑器提示“属性$q不存在”。
解决方案:扩展 Vue 全局属性接口,声明$q类型。
步骤
1. 创建类型声明文件:
// src/shims-vue.d.ts (项目根目录,若不存在则新建)
import { QVueGlobals } from 'quasar'
// 扩展 Vue 组件自定义属性接口
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$q: QVueGlobals // 声明 $q 为 QVueGlobals 类型
}
}
// 确保此文件被 TypeScript 识别(无需导出任何内容)
export {}
2. 效果:
完成后,在 Vue 组件、Boot 文件或外部工具中使用$q时,TypeScript 会自动提示其属性和方法(如$q.notify、$q.screen),避免类型错误。
三、注意事项
3.1 执行上下文限制
- 禁止在非 Vue 上下文调用useQuasar():useQuasar()依赖 Vue 的getCurrentInstance(),若在普通.ts文件(非组件/Composables)中直接调用,会抛出getCurrentInstance() is null错误。
- 正确时机:仅在 Vue 组件的<script setup>、setup()函数,或自定义 Composables(需在组件中调用)中使用useQuasar()。
- 避免useQuasar():Boot 文件在应用初始化阶段执行,此时 Vue 组件上下文尚未创建,直接调用useQuasar()会失败,需通过app.config.globalProperties.$q获取。
- SSR 兼容:在 SSR 模式下,Boot 文件可能运行在服务端,需注意避免使用依赖浏览器 API 的$q属性(如$q.cookies、$q.navigator)。
- DOM 相关 API 限制:在 SSR 环境中,$q的部分属性(如$q.body、$q.document)依赖浏览器 DOM,服务端调用会报错,需通过process.client判断环境:if (process.client) { // 仅在客户端执行
3.2 Boot 文件的特殊性
3.3 服务端渲染(SSR)注意事项
$q.body.addClass('dark') // 操作 DOM 类名
}
- 状态隔离:SSR 中$q实例为全局对象,需避免在服务端修改其状态(如$q.lang.set()),防止请求间状态污染。
总结
获取$q实例的核心是根据文件类型选择合适的方法:
- Vue 组件/Composables:直接调用useQuasar()(最简单、推荐);
- 外部.ts文件:通过依赖注入或全局实例管理工具传递$q;
- Boot 文件:从app.config.globalProperties中获取;
- TypeScript 类型:扩展ComponentCustomProperties接口。
遵循以上方法和注意事项,可在企业级项目中安全、高效地使用 Quasar 的$q功能,确保代码规范与类型安全。
浙公网安备 33010602011771号