loading...

Creating a VueJS component for online/offline events

jcalixte profile image Julien Calixte ・3 min read

Hi folks!

I've recently created a node module and I thought it could be interesting to review it together, if you want to publish a component that you use on multiple VueJS apps.

The component is named vue-online-offline.

Of course, there are others components and directives that can be used to know if your app is online or not. Be I find useful to have a small component with events & slots that can be used everywhere without any global variables, just a simple reusable component 😊.

Usage

Here an example when it can be used. (Pro tip: if you're displaying the same component and only change its properties, remember to add a key on your component to force VueJS to rerender it)

<template>
  <vue-online-offline @online="isOnline" @offline="isOffline">
    <ArticleList slot="online" key="online" :online="true" />
    <ArticleList slot="offline" key="offline" :online="false" />
  </vue-online-offline>
</template>

<script>
import VueOnlineOffline from 'vue-online-offline'

export default {
  components: { VueOnlineOffline },
  methods: {
    isOnline() {
      console.log(`Now I'm online!`)
      // Show toaster 'Success! you're online!'
    },
    isOffline() {
      console.log(`Now I'm offline.`)
      // Show toaster 'Information: you're now offline but you can still read your local articles.'
    }
  }
}
</script>

How does it work?

So, here is the component.

<template>
  <div class="online-view">
    <slot v-if="online" name="online"></slot>
    <slot v-else name="offline"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      online: navigator.onLine
    };
  },
  mounted() {
    window.addEventListener("online", this.onchange);
    window.addEventListener("offline", this.onchange);
    this.onchange();
  },
  beforeDestroy() {
    window.removeEventListener("online", this.onchange);
    window.removeEventListener("offline", this.onchange);
  },
  methods: {
    onchange() {
      this.online = navigator.onLine;
      this.$emit(this.online ? "online" : "offline");
    }
  }
};
</script>

It is quite simple with two slots and events emitted thanks to the online/offline events available.

Create and build the component

First, we will use the vue-cli command line tool: vue create vue-online-offline.

We can remove the components and assets folders as well as the main.js. Only the App.vue will be useful here, we replace the code with our own component.

Then VueJS command line tool lets you build a component for npmjs.org simply with a .vue file:

vue-cli-service build --target lib --name vue-online-offline

By default it will search for the App.vue file. You can look for more details in the documentation.

It will create a dist folder with your javascript files that will be used by other apps.

Publish as a node package!

We add the main property and specify the files in the package.json that's it! A new shiny package available for everyone! For instance, here my package.json :

{
  "name": "vue-online-offline",
  "version": "1.0.6",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name vue-online-offline",
    "lint": "vue-cli-service lint"
  },
  "main": "./dist/vue-online-offline.common.js",
  "license": "MIT",
  "files": [
    "dist/*"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/jcalixte/vue-online-offline"
  },
  "dependencies": {
    "core-js": "^3.3.2",
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.0.0",
    "@vue/cli-plugin-eslint": "^4.0.0",
    "@vue/cli-service": "^4.0.0",
    "babel-eslint": "^10.0.3",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "vue-template-compiler": "^2.6.10"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ],
  "keywords": [
    "vuejs",
    "vue",
    "component",
    "online",
    "offline",
    "slot",
    "event"
  ]
}

To publish, login & run the command npm publish.

VoilΓ  ! Hope you enjoyed this little tutorial! Let me know if you have any question, I'll be glad to answer it.

Love.

Posted on Oct 25 '19 by:

jcalixte profile

Julien Calixte

@jcalixte

Frontend & mobile developer in TypeScript/VueJS/React Native. Love building offline first PWAs. πŸ‡§πŸ‡·πŸ‡«πŸ‡·πŸ‡ͺπŸ‡Ί

Discussion

markdown guide
 

I'm not sure to understand, what is the problem that you are trying to solve? Is this a common pattern?

 

Hi!
You're right, I think I can be more precise on why to use this component.
This component can be useful when your app needs to display different things when the user is online and when he is offline. For example, I'm currently developing a PWA that stores articles for offline reading. With the component vue-online-offline, I can tell to an other <ArticleList /> component to stop fetching the API and only display articles stored locally. This way, I only display articles to the user he will be able to read.

More simple, it can be used to display or not an offline icon.

Is this more comprehensible?