Плагины для устройств

Плагины для устройств в экосистеме Quasar представляют собой обёртки над нативными возможностями мобильных платформ, браузера или настольных сред. Они позволяют работать с аппаратными функциями устройства через единый API, независимо от целевой платформы: SPA, PWA, Cordova, Capacitor или Electron.

Quasar не реализует доступ к устройствам самостоятельно — он интегрируется с такими решениями, как Cordova и Capacitor, предоставляя удобный слой взаимодействия внутри Vue-приложения.


Подключение и настройка

Работа с устройствами начинается с выбора режима сборки:

  • Cordova mode
  • Capacitor mode
  • Electron mode

Добавление режима:

quasar mode add capacitor

или:

quasar mode add cordova

После этого становятся доступны API соответствующей платформы.


Структура доступа к плагинам

В Quasar плагины устройств обычно подключаются через:

  1. Нативные плагины (Cordova / Capacitor)
  2. Quasar Boot-файлы
  3. Импорт API напрямую

Пример boot-файла:

// src/boot/device.js
import { boot } from 'quasar/wrappers'
import { Device } from '@capacitor/device'

export default boot(async ({ app }) => {
  const info = await Device.getInfo()
  app.config.globalProperties.$deviceInfo = info
})

Регистрация в quasar.config.js:

boot: ['device']

Работа с Capacitor

Capacitor — современный инструмент для доступа к нативным функциям.

Установка:

npm install @capacitor/core @capacitor/cli
npx cap init

Добавление платформ:

npx cap add android
npx cap add ios

Основные плагины устройств

Информация об устройстве

import { Device } from '@capacitor/device'

const info = await Device.getInfo()
console.log(info)

Доступные данные:

  • модель устройства
  • операционная система
  • версия OS
  • тип устройства (mobile, desktop)

Камера

import { Camera, CameraResultType } from '@capacitor/camera'

const photo = await Camera.getPhoto({
  resultType: CameraResultType.Uri
})

Ключевые параметры:

  • quality — качество изображения
  • allowEditing — разрешение редактирования
  • source — камера или галерея

Геолокация

import { Geolocation } from '@capacitor/geolocation'

const position = await Geolocation.getCurrentPosition()

Доступ:

  • широта и долгота
  • точность
  • время получения

Хранилище

import { Preferences } from '@capacitor/preferences'

await Preferences.set({
  key: 'username',
  value: 'admin'
})

const { value } = await Preferences.get({ key: 'username' })

Вибрация

import { Haptics, ImpactStyle } from '@capacitor/haptics'

await Haptics.impact({ style: ImpactStyle.Medium })

Работа с Cordova

Cordova использует плагины из репозитория:

cordova plugin add cordova-plugin-camera

Доступ через глобальный объект:

navigator.camera.getPicture(success, error, options)

В Quasar рекомендуется оборачивать такие вызовы в boot-файлы для унификации.


Различия Capacitor и Cordova

Характеристика Capacitor Cordova
Архитектура Современная Устаревающая
API Promise-based Callback-based
Поддержка Vue Отличная Ограниченная
Плагины Новые + совместимые Огромная база

Обработка разрешений

Для доступа к устройствам требуется разрешение пользователя.

Пример (геолокация):

const permission = await Geolocation.requestPermissions()

Результат:

{
  "location": "granted"
}

Платформенные особенности

Android

  • Разрешения указываются в AndroidManifest.xml
  • Требуется runtime-подтверждение

iOS

  • Настройки в Info.plist
  • Обязательное описание причин доступа

Использование в компонентах Vue

<script setup>
import { Camera } from '@capacitor/camera'

const takePhoto = async () => {
  const photo = await Camera.getPhoto({
    resultType: 'uri'
  })
}
</script>

Интеграция с Quasar UI

Часто используется вместе с компонентами:

  • QBtn — вызов функций устройства
  • QDialog — запрос разрешений
  • QImg — отображение изображений с камеры

Пример:

<q-btn label="Сделать фото" @click="takePhoto" />

Обработка ошибок

try {
  const photo = await Camera.getPhoto()
} catch (err) {
  console.error('Ошибка камеры', err)
}

Типичные ошибки:

  • отказ в разрешении
  • отсутствие устройства
  • неподдерживаемая платформа

Проверка платформы

Quasar предоставляет утилиту:

import { Platform } from 'quasar'

if (Platform.is.capacitor) {
  // мобильная среда
}

if (Platform.is.electron) {
  // desktop
}

Условная логика

if (Platform.is.mobile) {
  useCamera()
} else {
  uploadFile()
}

Lazy-загрузка плагинов

Для оптимизации:

const { Camera } = await import('@capacitor/camera')

Безопасность

  • проверка разрешений перед вызовом
  • минимизация запрашиваемых данных
  • использование HTTPS

Кастомные плагины

Создание собственного плагина:

npx cap plugin:generate

Структура:

  • android/
  • ios/
  • web/

Пример метода:

export interface MyPlugin {
  echo(options: { value: string }): Promise<{ value: string }>
}

Отладка

  • Chrome DevTools (Android)
  • Safari Web Inspector (iOS)
  • Логи Capacitor:
npx cap open android

Производительность

  • избегать частых вызовов API устройства
  • кешировать данные
  • использовать throttling для геолокации

Практические сценарии

1. Сканер QR-кодов

  • камера + сторонняя библиотека

2. Фото профиля

  • камера + загрузка на сервер

3. Отслеживание маршрута

  • геолокация + карта

4. Push-уведомления

  • Firebase + Capacitor Push API

Ограничения

  • не все плагины работают в браузере
  • различия API между платформами
  • необходимость тестирования на реальных устройствах

Рекомендации по организации кода

  • вынос работы с устройствами в отдельные сервисы
  • использование composables (Vue 3)

Пример:

export function useCamera() {
  const takePhoto = async () => {
    const { Camera } = await import('@capacitor/camera')
    return await Camera.getPhoto()
  }

  return { takePhoto }
}

Тестирование

  • эмуляторы (Android Studio, Xcode)
  • реальные устройства
  • unit-тесты с моками API

Расширение возможностей

Популярные плагины:

  • Filesystem
  • Network
  • Clipboard
  • Share
  • App

Интеграция с Electron

В режиме Electron доступ к устройствам осуществляется через Node.js API:

const { desktopCapturer } = require('electron')

Управление состоянием

Данные устройств часто сохраняются в:

  • Pinia
  • Vuex (устаревший подход)

Пример:

const store = useDeviceStore()
store.setLocation(position)

Асинхронность и реактивность

Работа с устройствами всегда асинхронная:

  • Promises
  • async/await

Интеграция с реактивностью:

const location = ref(null)

location.value = await Geolocation.getCurrentPosition()

Итоговая структура проекта

src/
 ├─ boot/
 │   └─ device.js
 ├─ composables/
 │   └─ useCamera.js
 ├─ services/
 │   └─ deviceService.js

Такой подход обеспечивает:

  • переиспользуемость
  • тестируемость
  • чистую архитектуру