DEV Community

Julien Calixte
Julien Calixte

Posted on

Creating a VueJS component for online/offline events

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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"
  ]
}
Enter fullscreen mode Exit fullscreen mode

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.

Latest comments (2)

Collapse
 
xowap profile image
Rémy 🤖

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

Collapse
 
jcalixte profile image
Julien Calixte

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?