eagleye

在 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功能,确保代码规范与类型安全。

 

posted on 2025-08-30 13:08  GoGrid  阅读(12)  评论(0)    收藏  举报

导航