Fermer

novembre 13, 2018

Vue hors ligne première applications avec capuche et boîte de travail


Apprenez à créer une application Offline-First dans Vue avec Hoodie et Workbox. Vous en apprendrez plus sur Offline-First, les techniciens de service et quelques stratégies de mise en cache.

Offline-First est une approche du développement logiciel où l'absence de connexion réseau n'est pas traitée comme une erreur. Vous commencez par développer l'application pour qu'elle fonctionne dans les zones sans connexion Internet. Ensuite, au fur et à mesure que les utilisateurs entrent dans des zones avec une connexion réseau ou que leur vitesse de connexion s'améliore, l'application est progressivement améliorée pour offrir davantage de fonctionnalités. Pour ce tutoriel, nous souhaitons pouvoir ajouter et supprimer des données lorsque les utilisateurs sont en mode hors connexion ou en ligne. C'est là que Hoodie va aider.

Hoodie est un backend JavaScript pour les applications Web Offline-First. Il fournit une API frontale pour vous permettre de stocker et de gérer des données et d'ajouter une authentification d'utilisateur. Il stocke les données localement sur le périphérique et, en cas de connexion réseau, les synchronise avec le serveur et résout les conflits de données. Il utilise PouchDB sur le client et CouchDB et hapi pour le serveur. Nous l'utilisons à la fois pour l'authentification de l'utilisateur et le stockage des articles.

Nous allons construire l'exemple d'application avec Vue.js et un Service Worker qui sera généré avec . . Voici un aperçu de ce que nous allons construire:

 application de liste de courses

Configuration de développement

Pour configurer votre environnement, clonez les fichiers sur https://github.com/pmbanugo/shopping-list-vue-starter . Clonez et installez les dépendances du projet en exécutant les commandes suivantes dans votre ligne de commande:

 git clone https://github.com/pmbanugo/shopping-list-vue-starter.git
cd liste de courses-starter-vue /
npm installer

Les dépendances installées sont Hoodie et Workbox CLI. Le fichier package.json devrait ressembler à ceci:

 {
  "nom": "liste de courses",
  "version": "1.0.0",
  "la description": "",
  "scripts": {
    "test": "echo " Erreur: aucun test spécifié  "&& exit 1",
    "start": "hoodie"
  },
  "licence": "ISC",
  "dépendances": {
    "sweat à capuche": "28.2.2"
  },
  "devDependencies": {
    "workbox-cli": "3.6.2"
  }
}

En cours de fonctionnement npm start démarre le backend Hoodie et vous indique l'URL pour y accéder. Par défaut, il s'agit de http://127.0.0.1:8080 . Les fichiers contenus dans le répertoire public sont les pages et les fichiers CSS nécessaires au rendu d'une belle interface utilisateur. Tous les éléments du dossier public, tels que les images, les fichiers CSS et les fichiers JavaScript, seront servis par le composant Hoodie Backend le http://127.0.0.1:8080/ .

Ajout de composants partagés

Nous allons avoir deux pages – la maison et l'histoire.

 page d'accueil

 page d'histoire

Ces pages partageront le même en-tête de navigation et composants d'authentification. Pour cette raison, ajoutez un fichier shared.js dans le dossier js avec le contenu suivant:

 Vue.component ("register-dialog", {
  data: function () {
    revenir {
      Nom d'utilisateur: "",
      mot de passe: ""
    };
  },
  accessoires: ["toggleLoggedIn"],
  modèle: `
      

Register

`,   méthodes: {     closeRegister: function () {       const registerDialog = document.querySelector ("# registre-dialogue");       dialogPolyfill.registerDialog (registerDialog);       registerDialog.close ();     },     enregistrer: function () {       let options = {nom d'utilisateur: this.username, mot de passe: this.password};       hoodie.account         .signUp (options)         .then (account => {           retourner hoodie.account.signIn (options);         })         .then (account => {           this.toggleLoggedIn ();           this.closeRegister ();           compte de retour;        })         .catch (error => {           console.log (erreur);           document.querySelector ("# register-error"). innerHTML =             "Une erreur s'est produite lors de l'enregistrement";         });     }   } });

Le code ci-dessus enregistre un composant register-dialog . Nous avons une fonction register () qui appelle hoodie.account.signUp () pour enregistrer un nouvel utilisateur. L’API de compte de Hoodie vous permet d’authentifier des utilisateurs, par exemple d’enregistrer de nouveaux utilisateurs et de les connecter et les déconnecter. L'objet hoodie est disponible, car nous ajouterons ultérieurement une référence de script à la bibliothèque Hoodie dans nos pages.

Ajoutez le code suivant au même fichier pour un composant de connexion et de navigation:

 Vue .component ("navigation", {
  accessoires: ["isLoggedIn", "toggleLoggedIn"],
  template: ` »,

  méthodes: {
    showLogin: function () {
      const loginDialog = document.querySelector ("# login-dialog" ");
      dialogPolyfill.registerDialog (loginDialog);
      loginDialog.showModal ();
    },
    showRegister: function () {
      const registerDialog = document.querySelector ("# registre-dialogue");
      dialogPolyfill.registerDialog (registerDialog);
      registerDialog.showModal ();
    },
    déconnexion: function () {
      hoodie.account
        .Déconnexion()
        .then (() => {
          this.toggleLoggedIn ();
          window.location.reload ();
        })
        .catch (error => {
          alert ("Impossible de se déconnecter");
        });
    }
  }
});

Vue.component ("login-dialog", {
  data: function () {
    revenir {
      Nom d'utilisateur: "",
      mot de passe: ""
    };
  },
  accessoires: ["toggleLoggedIn"],
  template: `
      

Login

`,   méthodes: {     closeLogin: function () {       const loginDialog = document.querySelector ("# login-dialog" ");       dialogPolyfill.registerDialog (loginDialog);       loginDialog.close ();     },     login: fonction (événement) {       hoodie.account         .se connecter({           nom d'utilisateur: this.username,           mot de passe: this.password         })         .then (() => {           this.toggleLoggedIn ();           this.closeLogin ();         })         .catch (error => {           console.log (erreur);           document.querySelector ("# erreur de login"). innerHTML = "Erreur de connexion";         });     }   } });

Ci-dessus, nous avons le composant login-dialog . Il gère la connexion et appelle hoodie.account.signIn () pour connecter les utilisateurs. Nous disposons également du composant navigation qui crée un en-tête de navigation avec des boutons permettant de déclencher les composants de registre et de connexion. et un bouton de déconnexion. Le bouton de déconnexion appelle la fonction logout () qui gère la déconnexion des utilisateurs en appelant hoodie.account.signOut () . Avec ces composants en place, nous devons maintenant créer les pages réelles.

L’application permet aux utilisateurs d’ajouter des articles à leur liste d’achats. Nous allons ajouter une page qui permet aux utilisateurs d'ajouter et de supprimer des éléments, puis de sauvegarder la liste. Ajoutez un fichier nommé index.html avec le contenu suivant:





  
  
  
  
   Liste d'achat 

  
  
     



  

Liste

Nom de l'article Coût Quantité Sous-total                     
{{item.name}} {{item.cost}} {{item.quantity}} {{item.subTotal}}                     

Le coût total: {{total}}

          
          
            
            
                         
          
        
      
    
                 
           

Ce fichier contient des balises permettant d'ajouter, de supprimer et d'enregistrer une liste de courses. En bas, nous avons ajouté une référence au client Hoodie, à Vue.js, au fichier shared.js que nous avons ajouté précédemment et à index.js, que nous ajouterons bientôt. Le client Hoodie sera servi par le serveur Hoodie une fois l'application lancée. Le fichier actuel se trouve dans .hoodie / client.js dans le répertoire du projet racine.

Ensuite, nous ajoutons le fichier index.js avec le contenu du fichier sous la forme:

 const vm = new Vue ({
  el: "#app",
  Les données: {
    prénom: "",
    Coût: "",
    quantité: "",
    articles: [],
    isLoggedIn: false
  },
  calculé: {
    total: fonction () {
      retourne this.items.reduce (
        (accumulator, currentValue) => accumulator + currentValue.subTotal,
        0
      )
    }
  },
  méthodes: {
    toggleLoggedIn: function () {
      this.isLoggedIn =! this.isLoggedIn;
    },
    onSubmit: function (event) {
      if (this.name && this.cost && this.quantity) {
        hoodie.store.withIdPrefix ("item"). add ({
          nom: this.name,
          coût: this.cost,
          quantité: this.quantity,
          sous-total: this.cost * this.quantity
        });

        this.name = "";
        this.cost = "";
        this.quantity = "";
      } autre {
        const snackbarContainer = document.querySelector ("# toast");
        snackbarContainer.MaterialSnackbar.showSnackbar ({
          message: "Tous les champs sont obligatoires"
        });
      }
    }
  },
  créé() {
    hoodie.store.withIdPrefix ("item"). sur ("add", item => vm.items.push (item));

    // récupère les éléments de la liste actuelle
    hoodie.store
      .withIdPrefix ("item")
      .Trouver tout()
      .then (items => (vm.items = items));

    hoodie.account.get ("session"). then (fonction (session) {
      si (! session) {
        // l'utilisateur est distingué
        vm.isLoggedIn = false;
      } else if (session.invalid) {
        vm.isLoggedIn = false;
      } autre {
        // l'utilisateur est connecté
        vm.isLoggedIn = true;
      }
    });
  }
});

Dans le code ci-dessus, nous avons initialisé une instance de Vue. Il a des valeurs de données pour contenir des valeurs d'état, une propriété calculée pour obtenir le coût total de la liste, le hook de cycle de vie créé et certaines fonctions de la propriété methods . La fonction onSubmit enregistre l'élément dans Hoodie en appelant hoodie.store.withIdPrefix ("item"). Add (..) . Il s'agit de l'API de magasin Hoodie qui permet de stocker et de récupérer des données pour chaque utilisateur. Vous pouvez appeler hoodie.store.add () pour stocker des données, mais nous avons utilisé hoodie.store.withIdPrefix ("item") pour stocker les éléments séparément. conteneur, et plus tard, nous utiliserons la même approche pour stocker les données de la liste d’achat sauvegardées dans un conteneur séparé. Lorsque Hoodie stocke ces données, il déclenche un événement add et, si l'utilisateur est connecté à d'autres périphériques, il synchronise et déclenche le même événement. Cet événement est traité à la ligne 41. Les lignes 44 à 47 chargent les données lors du chargement de la page, tandis que les lignes 49 à 58 vérifient si l'utilisateur est connecté.

Pour supprimer des éléments sauvegardés ou les enregistrer sous forme de liste, nous ajouterons des fonctions pour supprimer un élément et un autre pour enregistrer les éléments sous forme de liste. Ajoutez le code suivant en tant qu'addition à l'option de méthode existante de l'instance Vue:

 // line 38

    deleteRow: function (itemId) {
      hoodie.store.withIdPrefix ("item"). remove (itemId);
    },

    saveList: function () {
      hoodie.store
        .withIdPrefix ("item")
        .Trouver tout()
        .then (items => {
          // stocke la liste
          hoodie.store.withIdPrefix ("list"). add ({
            coût: ce.total,
            articles: articles
          });

          // supprime les éléments
          hoodie.store
            .withIdPrefix ("item")
            .supprimer des éléments)
            .then (() => {
            //Débarrasse la table
            this.items = [];

            // notifier l'utilisateur
            var snackbarContainer = document.querySelector ("# toast");
            snackbarContainer.MaterialSnackbar.showSnackbar ({
                message: "Liste enregistrée avec succès"
            });
            })
            .catch (fonction (erreur) {
            // notifier l'utilisateur
            var snackbarContainer = document.querySelector ("# toast");
            snackbarContainer.MaterialSnackbar.showSnackbar ({
                message: error.message
            });
            });
        });
    }

La fonction deleteRow supprime un élément, tandis que saveList enregistre les éléments sous forme de liste. Sur la méthode créée du cycle de vie, ajoutez le code suivant:

 hoodie.store
  .withIdPrefix ("item")
  .sur(
    "retirer",
    deleteItem =>
      (vm.items = vm.items.filter (item => item._id! == deleteItem._id))
  )

Ceci écoute l’événement remove et met à jour l’état en conséquence.

Voyons ce que nous avons obtenu jusqu’à présent! Ouvrez la ligne de commande et exécutez npm start pour démarrer le serveur Hoodie. Ouvrez votre navigateur pour localhost: 8080 . Essayez d'ajouter et de supprimer des éléments. En outre, enregistrez-vous et connectez-vous à un utilisateur pour voir les données se synchroniser sur les navigateurs / appareils à mesure que vous ajoutez et supprimez des éléments.

 hoodie-vue.gif

Il fonctionne également hors ligne! Pour tester ceci:

  • Connectez-vous avec le même utilisateur sur différents navigateurs
  • Arrêtez le serveur à capuchon (ouvrez la fenêtre de ligne de commande où vous avez exécuté npm start et appuyez sur Ctrl + C pour arrêter le processus en cours. )
  • Ouvrez les navigateurs et ajoutez ou supprimez des éléments
  • . Démarrez le serveur Hoodie et regardez la mise à jour des données sur tous les navigateurs

. Voici l'avantage de Offline-First. Les applications fonctionnent même lorsque le serveur est arrêté ou que l'utilisateur manque de connectivité.

Affichage de l'historique des achats

Dans la section précédente, nous avons un code pour ajouter et supprimer des éléments et enregistrer les éléments sous forme de liste. Ces listes sauvegardées que nous voulons voir comme l'historique des achats, avec une liste de chaque coût d'achat et leur date. Ajoutez un nouveau fichier history.html dans le dossier public avec le contenu ci-dessous:





  
  
  
  
   Liste d'achats 

  
  
     



  

Historique

  • {{new Date (item.hoodie.createdAt) .toDateString ()}} Coût: $ {{item.cost}}                              
  •             
          
          
            
            
                         
          
        
      
    
            
           

Dans le code ci-dessus, les lignes 30 à 38 parcourent la liste sauvegardée et affichent le contenu approprié. Ajoutez un nouveau fichier history.js dans le dossier js.

 const vm = new Vue ({
  el: "#app",
  Les données: {
    liste: [],
    isLoggedIn: false
  },
  méthodes: {
    toggleLoggedIn: function () {
      this.isLoggedIn =! this.isLoggedIn;
    }
  },
  créé() {
    hoodie.store
      .withIdPrefix ("liste")
      .Trouver tout()
      .then (savedList => (vm.list = savedList));

    hoodie.account.get ("session"). then (fonction (session) {
      si (! session) {
        // l'utilisateur est distingué
        vm.isLoggedIn = false;
      } else if (session.invalid) {
        vm.isLoggedIn = false;
      } autre {
        // l'utilisateur est connecté
        vm.isLoggedIn = true;
      }
    });
  }
});

Le code ci-dessus obtient la liste enregistrée dans son intégralité à partir du magasin Hoodie et définit l'état de la liste avec le résultat. Ouvrez votre navigateur et accédez à la page d'historique.

 history page.png

Nous disposons maintenant de l'application complète pour stocker et récupérer les données, même dans des scénarios hors ligne! Mais, lorsque nous ouvrons l'application ou naviguons vers une autre page en mode hors connexion, la page ne se charge pas. Ne serait-il pas intéressant de charger également des pages hors connexion? Nous rendrons cela possible grâce aux services de personnel.

Ajout de personnel de service

Un Service Worker est un proxy réseau programmable qui s'exécute sur un thread de navigateur distinct. Il vous permet d'intercepter les demandes réseau et de les traiter à votre guise. Vous pouvez intercepter et mettre en cache une réponse du serveur et, lors de la prochaine demande de l'application pour cette ressource, vous pourrez envoyer la version mise en cache. Elle fonctionne indépendamment du fait que la page soit actuellement ouverte ou non.

Nous allons ajouter un script Service Worker qui interceptera toutes les demandes réseau et répondra avec une version mise en cache si la ressource fait référence à notre page et à ses actifs associés. Cette ressource sera mise en cache à l'aide de l'API de cache .

L'API de cache, qui fait partie de la spécification Service Worker, permet aux agents de service de mettre en cache des demandes réseau afin qu'elles puissent fournir les réponses appropriées même en mode hors connexion.

Nous allons générer un script Service Worker à l'aide de Workbox . Workbox est un ensemble de bibliothèques de Service Worker permettant de créer facilement des applications Web progressives. Nous allons utiliser la CLI de Workbox pour générer ce script afin de ne pas avoir à l'écrire à partir de zéro. Nous avons installé la CLI de Workbox en même temps que les dépendances du projet de démarrage. Nous aurons besoin d’un fichier de configuration pour indiquer à la CLI ce qu’il faut inclure dans le script qu’elle va générer. Ajoutez un nouveau fichier workbox-config.js dans le répertoire racine du projet avec ce contenu:

 module.exports = {
  globDirectory: "public /",
  globPatterns: ["**/*.{css,ico,html,png,js,json,woff2}"],
  swDest: "./public/sw.js",
  sauterAttendre: vrai,
  clientsClaim: true,
  templatedUrls: {
    "/hoodie/client.js": ".hoodie / cleint.js"
  }
};

Le globDirectory lui indique le répertoire dans lequel il doit sélectionner les fichiers et globPatterns dicte le type de fichiers à mettre en cache. L'option swDest lui indique où stocker le script généré. templatedUrls lui indique où choisir le script Hoodie à mettre en cache; then skipWaiting et clientsClaim sont paramétrés sur true, car nous souhaitons pouvoir publier un nouveau Service Worker et le faire mettre à jour et contrôler une page Web dès que possible, en sautant le . ] cycle de vie par défaut du travailleur de service . Pour en savoir plus sur ces options de configuration, consultez les documents .

Ouvrez la ligne de commande et exécutez la boîte de travail generateSW . Cela devrait générer un fichier sw.js dans un dossier public. Ouvrez shared.js et ajoutez le code suivant en haut du fichier

 if ("serviceWorker" dans le navigateur) {
  navigator.serviceWorker
    .register ("sw.js")
    .then (console.log)
    .catch (console.error);
}

Ceci vérifie si le navigateur prend en charge les opérateurs de service. Si tel est le cas, il enregistre le fichier en tant que script Service Worker, ce qui lui permet de prendre le contrôle de la page et d’intercepter les requêtes réseau. Démarrez le serveur Hoodie et ouvrez l'application. Il devrait enregistrer le technicien de service et afficher quelque chose comme ceci dans la console:

 Capture d'écran 2018-10-15 à 10.27.42.png

Lorsque vous accédez à une autre page, les fichiers doivent être chargés. extrait de la cache.

 Capture d'écran 2018-10-15 à 10.28.25.png

Un rêve!

Nous avons créé une application Vue hors ligne en premier. Nous l'avons construit avec Hoodie et Workbox. Nous avons utilisé l'API d'authentification pour gérer l'authentification de l'application et l'API de magasin pour stocker et récupérer des données. Nous avons vu comment il gérait les données hors ligne et en ligne. Avec Workbox, nous avons facilement généré un script Service Worker pour mettre en cache les actifs de l’application afin qu’elle puisse se charger hors connexion. Vous pouvez trouver la source d'application complétée sur GitHub .


Pour plus d'informations sur Vue : Vous souhaitez en savoir plus sur la création d'interfaces utilisateur de qualité avec Vue? Découvrez Kendo UI pour Vue avec des éléments tels que des grilles et des tableaux, des planificateurs et des sélecteurs, et n'oubliez pas de consulter cet autre excellent contenu de Vue:


Les commentaires sont désactivés en mode Aperçu.




Source link