Как создать сканер QR-кодов Quasar с помощью Capacitor

Quasar — это фреймворк на базе Vue.js, который позволяет веб-разработчикам быстро создавать отзывчивые веб-сайты/приложения, а Capacitor — это среда выполнения для создания кросс-платформенных iOS, Android и Progressive Web Apps с помощью JavaScript, HTML и CSS.

В этой статье мы будем использовать их для создания сканера QR-кодов с помощью плагина capacitor для Dynamsoft Barcode Reader. Приложение может работать как веб-приложение, приложение для Android и iOS.

Онлайн-демонстрация.

Ознакомьтесь со статьей Ionic Vue, если вы предпочитаете использовать фреймворк Ionic.

Построение сканера QR-кодов Quasar с использованием Capacitor

Новый проект

Установите quasar cli:

npm install -g @quasar/cli
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Затем используйте его для создания нового проекта:

npm init quasar
Войти в полноэкранный режим Выйти из полноэкранного режима

Поскольку приложение должно работать в webview Android, для совместимости мы выбрали Quasar v1 + Vue.js 2 + Composition API для создания этого приложения.

√ What would you like to build? » App with Quasar CLI, let's go!
√ Project folder: ... quasar-qrcode-scanner
√ Pick Quasar version: » Quasar v1 (Vue 2)
√ Pick script type: » Typescript
√ Package name: ... quasar-qrcode-scanner
√ Project product name: (must start with letter if building mobile apps) ... Quasar QR Code Scanner
√ Project description: ... A Quasar Project
√ Author: ...
√ Pick a Vue component style: » Composition API (recommended) (https://github.com/vuejs/composition-api)
√ Pick your CSS preprocessor: » Sass with SCSS syntax
√ Pick a Quasar components & directives import strategy: (can be changed later) » * Auto-import in-use Quasar components & directives
        - also treeshakes Quasar; minimum bundle size
√ Check the features needed for your project: » ESLint
√ Pick an ESLint preset: » Prettier
Вход в полноэкранный режим Выход из полноэкранного режима

Установите зависимости

npm install capacitor-plugin-dynamsoft-barcode-reader
Войти в полноэкранный режим Выход из полноэкранного режима

Изменение файлов по умолчанию

  1. Удалите примеры компонентов в src/components.
  2. Откройте src/layouts/MainLayout.vue, упростите его шаблон со следующим содержимым:
   <template>
     <q-layout view="lHh Lpr lFf">
       <q-header elevated >
         <q-toolbar>
           <q-toolbar-title>
             QR Code Scanner
           </q-toolbar-title>
         </q-toolbar>
       </q-header>
       <q-page-container>
         <router-view />
       </q-page-container>
     </q-layout>
   </template>
Вход в полноэкранный режим Выйти из полноэкранного режима
  1. Откройте src/pages/Index.vue, добавьте плавающую кнопку действия для запуска страницы сканера для сканирования QR-кодов и QList для отображения результатов. Пользователи могут щелкнуть элемент, чтобы скопировать результат.
   <template>
     <q-page class="row justify-evenly">
       <div class="full">
         <q-list v-if="results.barcodeResults.value.length>0" dense bordered separator padding class="rounded-borders">
           <q-item @click="copy(result.barcodeText)" clickable v-ripple v-for="(result, index) in results.barcodeResults.value" :key="index">
             <q-item-section>
               <q-item-label :lines="1">{{ result.barcodeText }}</q-item-label>
               <q-item-label caption>{{ result.barcodeFormat }}</q-item-label>
             </q-item-section>
           </q-item>
         </q-list>
         <q-page-sticky position="bottom-left" :offset="[18,18]">
           <q-btn @click="goScan" fab icon="camera_alt" color="blue" />
         </q-page-sticky>
       </div>
     </q-page>
   </template>
Вход в полноэкранный режим Выход из полноэкранного режима

Функции goScan и copy:

   import { Clipboard } from '@capacitor/clipboard';
   import { Notify } from 'quasar';
   const goScan = async () => {
     await router.push('/scanner');
   }

   const copy = async (text:string) => {
     await Clipboard.write({
       string: text
     });
     Notify.create({
       message: 'Copied.'
     });
   }
Вход в полноэкранный режим Выход из полноэкранного режима
  1. Используйте vue-router с API композиции для перехода на другую страницу.

Зависимый vue-router текущей версии quasar не имеет useRoute и useRouter для использования в Vue 2.7 с API композиции. Мы можем использовать следующее обходное решение (проблема на GitHub).

  1. Создайте файл в каталоге utils/index.js.

      import { getCurrentInstance } from 'vue'
    
      export function useRoute() {
        const { proxy } = getCurrentInstance()
        const route = proxy.$route
        return route
      }
      export function useRouter() {
        const { proxy } = getCurrentInstance()
        const router = proxy.$router
        return router
      }
    
  2. На индексной странице используйте его для перехода на страницу сканера.

      import { useRouter } from '../utils/index.js'
      export default defineComponent({
        name: 'PageIndex',
        components: {},
        setup() {
          const router = useRouter();
          const goScan = async () => {
            await router.push('/scanner');
          }
          return {goScan};
        }
      });
    

Скриншот индексной страницы:

Добавление страницы сканера

  1. Создайте новый файл с именем Scanner.vue в srcpages.
  2. Откройте src/router/routes.ts, чтобы зарегистрировать маршрут для страницы сканера.
   {
     path: '/scanner',
     component: () => import('pages/Scanner.vue')
   },
Вход в полноэкранный режим Выйдите из полноэкранного режима
  1. Добавьте компонент QR Code Scanner. Мы определили компонент в предыдущей статье по Ionic Vue. Хотя тот проект выполнен на Vue 3, мы все еще можем напрямую использовать компонент в проекте Vue 2 с включенным composition api. Мы поместим vue-файл в src/components/QRCodeScanner.vue.

  2. Используйте компонент QR Code Scanner на странице сканера.

   <template>
     <q-layout view="lHh Lpr lFf">
       <QRCodeScanner
         license="DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="
         :torchOn="torchOn"
         :zoomFactor="zoomFactor"
         :runtimeSettings="runtimeSettings"
         @onScanned="onScanned"
         @onPlayed="onPlayed"
       ></QRCodeScanner>
     </q-layout>
   </template>
   <script lang="ts">

   export default defineComponent({
     name: 'PageScanner',
     components: { QRCodeScanner },
     setup() {
       const scanned = ref(false);
       const zoomFactor = ref(1.0);
       const torchOn = ref(false);
       const runtimeSettings = ref('');
       const router = useRouter();

       const onPlayed = (resolution:string) => {
         console.log(resolution);
       }
       const onScanned = (result:ScanResult) => {
         console.log(result);
       };

       onMounted(() => {
         zoomFactor.value = 1.0;
         App.addListener("backButton",() => {
           router.go(-1);
         });
       });

       return {onPlayed, onScanned, goBack, zoomFactor, runtimeSettings};
     }});
    </script>
Войдите в полноэкранный режим Выход из полноэкранного режима
  1. Добавьте плавающую кнопку действия для отмены сканера и управления состоянием факела и зума.

Шаблон:

   <q-page-sticky style="z-index:1;" position="bottom-left" :offset="[18,18]">
     <q-fab color="blue" icon="keyboard_arrow_up" direction="up">
       <q-fab-action @click="toggleTorch" color="blue" icon="flashlight_on" />
       <q-fab-action @click="zoomIn" color="blue" icon="add" />
       <q-fab-action @click="zoomOut" color="blue" icon="remove" />
       <q-fab-action @click="goBack" color="blue" icon="arrow_back" />
     </q-fab>
   </q-page-sticky>
Вход в полноэкранный режим Выйти из полноэкранного режима

Скрипт:

   const zoomFactor = ref(1.0);
   const torchOn = ref(false);
   const toggleTorch = () => {
      torchOn.value = ! torchOn.value;
    };

   const zoomIn = () => {
     zoomFactor.value = zoomFactor.value + 0.3;
   };

   const zoomOut = () => {
     zoomFactor.value = Math.max(zoomFactor.value - 0.3, 1.0);
   };

   const goBack = () => {
     update([]);
     router.go(-1);
   }
Войти в полноэкранный режим Выход из полноэкранного режима

Скриншот страницы сканера:

Создание хранилища для передачи результатов QR-кода на индексную страницу

Мы можем создать магазин для обмена данными между различными страницами с помощью Vuex.

  1. Создайте новый магазин Vuex с именем barcodes.
   quasar new store barcodes
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Это добавит следующие файлы в проект:

   .
   └── src/
       └── store/
           ├── index.js         # Vuex Store definition
           └── barcodes         # Module "barcodes"
               ├── index.js     # Gluing the module together
               ├── actions.js   # Module actions
               ├── getters.js   # Module getters
               ├── mutations.js # Module mutations
               └── state.js     # Module state
Войти в полноэкранный режим Выйти из полноэкранного режима
  1. Отредактируйте src/store/index.js, чтобы добавить ссылку на новый модуль.
   export default function (/* { ssrContext } */) {
     const Store = new Vuex.Store({
       modules: {
   +     barcodes
       },

       strict: process.env.DEBUGGING
     })

     return Store
   }
Вход в полноэкранный режим Выход из полноэкранного режима
  1. Обновите state.js для определения состояний и mutations.js для определения сеттера.
   // src/store/barcodes/mutations.js
   export function update(state, results) {
     state.barcodeResults = results;
   }

   // src/store/barcodes/state.js
   // Always use a function to return state if you use SSR
   export default function () {
     return {
       barcodeResults: []
     }
   }
Вход в полноэкранный режим Выход из полноэкранного режима
  1. На странице сканера, если QR-коды найдены, обновите состояние и вернитесь на индексную страницу.
   import { createNamespacedHelpers } from 'vuex-composition-helpers';
   const { useMutations } = createNamespacedHelpers('barcodes');
   //...
   setup() {
     const { update } = useMutations(['update']);
     const onScanned = (result:ScanResult) => {
       if (result.results.length>0 && scanned.value == false) {
         scanned.value = true;
         update(result.results);
         router.go(-1);
       }
     };
   }
Вход в полноэкранный режим Выход из полноэкранного режима
  1. На индексной странице загрузите результаты с помощью useState.
   import { createNamespacedHelpers } from 'vuex-composition-helpers';
   const { useState } = createNamespacedHelpers('barcodes');
   setup() {
     const results = useState(["barcodeResults"]);
   }
Войти в полноэкранный режим Выход из полноэкранного режима

Итак, мы закончили написание страницы. Мы можем выполнить следующие действия, чтобы протестировать страницу:

quasar dev
Войти в полноэкранный режим Выйти из полноэкранного режима

Использование Capacitor для создания приложений для Android и iOS

Мы можем сделать еще один шаг дальше и превратить веб-приложение в приложение для Android или iOS с помощью Capacitor. В quasar cli есть режим Capacitor, но он использует Capacitor v2. Мы будем использовать непосредственно Capacitor v4.

  1. Бросьте Capacitor в проект:
   npm install @capacitor/cli @capacitor/core
   npx cap init
Войдите в полноэкранный режим Выйти из полноэкранного режима
  1. Затем мы можем создавать проекты для Android и iOS.
   npm install @capacitor/ios @capacitor/android
   npx cap add ios
   npx cap add android
Войти в полноэкранный режим Выйти из полноэкранного режима
  1. Создайте веб-активы и синхронизируйте файлы с проектами.
   npm run build
   npx cap sync
Войти в полноэкранный режим Выход из полноэкранного режима
  1. Используйте следующие команды для запуска приложения:
   npx cap run android // run on Android devices
   npx cap run ios // run on iOS devices
Войти в полноэкранный режим Выйти из полноэкранного режима

Необходимо выполнить дополнительные действия.

  • Для платформы iOS:

Добавьте разрешение камеры в Info.plist.

   <key>NSCameraUsageDescription</key>
   <string>For barcode scanning</string>
Вход в полноэкранный режим Выход из полноэкранного режима
  • Для платформы Android нам, возможно, придется обрабатывать событие кнопки «Назад» с помощью плагина @capacitor/app:
   import { App } from '@capacitor/app';
   App.addListener("backButton",() => {
     console.log("back pressed");
   });
Вход в полноэкранный режим Выход из полноэкранного режима
  • Для обеих платформ включите viewport-fit=cover в index.template.html, чтобы страница не блокировалась строкой состояния.
   - <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover <% } %>">
   + <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, viewport-fit=cover">
Вход в полноэкранный режим Выход из полноэкранного режима

Исходный код

https://github.com/tony-xlh/Quasar-QR-Code-Scanner

Оцените статью
devanswers.ru
Добавить комментарий