Creating a VueJS component for online/offline events
Tags: vue, component, package, publish
Published: 2019-11-14 20:03:29

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](https://www.npmjs.com/package/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)

```vue
<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.

```vuejs
<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](https://cli.vuejs.org/guide/build-targets.html#library).

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 :

```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`](https://docs.npmjs.com/cli/publish).

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

Love.