{"id":18879736,"url":"https://github.com/loilo/vue-reactivator","last_synced_at":"2026-02-20T04:30:19.518Z","repository":{"id":34407414,"uuid":"178611917","full_name":"loilo/vue-reactivator","owner":"loilo","description":"Create reactive Vue properties from arbitrary global state","archived":false,"fork":false,"pushed_at":"2023-03-07T04:58:48.000Z","size":26,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-17T03:18:25.553Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loilo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-30T21:12:53.000Z","updated_at":"2022-01-03T08:52:12.000Z","dependencies_parsed_at":"2024-09-18T16:47:41.880Z","dependency_job_id":null,"html_url":"https://github.com/loilo/vue-reactivator","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Fvue-reactivator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Fvue-reactivator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Fvue-reactivator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loilo%2Fvue-reactivator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loilo","download_url":"https://codeload.github.com/loilo/vue-reactivator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239841742,"owners_count":19705981,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T06:39:05.671Z","updated_at":"2026-02-20T04:30:19.486Z","avatar_url":"https://github.com/loilo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n\n![Reactivator logo showing a Newton's Cradle](https://cdn.jsdelivr.net/gh/Loilo/vue-reactivator@HEAD/reactivator.svg)\n\n  \u003cbr\u003e\n\u003c/div\u003e\n\n# Reactivator\n\n[![Tests](https://badgen.net/github/checks/loilo/vue-reactivator/master)](https://github.com/loilo/vue-reactivator/actions)\n[![Version on npm](https://badgen.net/npm/v/vue-reactivator)](https://www.npmjs.com/package/vue-reactivator)\n\nReactivator is a tiny Vue mixin (0.5KB minified \u0026 gzipped) which enables you to create reactive properties from arbitrary non-reactive state.\n\n## Motivation\n\nThere is global state all around that is completely unrelated to Vue. A lot of it is mutable, for example your browser's viewport size. Wouldn't it be nice to use those as reactive properties in Vue?\n\n```vue\n\u003cdiv\u003eYour browser viewport dimensions are {{ size[0] }}x{{ size[1] }} pixels.\u003c/div\u003e\n```\n\nThis is what Reactivator is for. Given an according implementation, it will take some non-reactive state and turn it into a reactive property in your Vue components.\n\nThere are already some handy browser-related Reactivator implementations in the [`vue-browser-state`](https://github.com/Loilo/vue-browser-state) package. However, Reactivator is not limited to browser-related state. Do you use Vue for only small parts of your website? Then you may encounter situations where you want to react to changes that are happening _outside_ of your components. This can be handled by your own custom implementations. If you want to know how to write those, take a look at the [Write Reactivator Implementations](#write-reactivator-implementations) section.\n\n## Installation\n\nReactivator is available on npm:\n\n```bash\nnpm install vue-reactivator\n```\n\nAfter installing, you can include it in the usual ways — via good ol' `require`...\n\n```js\nconst reactivator = require('vue-reactivator')\n```\n\n...or as an ES module:\n\n```js\nimport reactivator from 'vue-reactivator'\n```\n\n---\n\nIf you want to play around or just prefer coding that way, you can also get Reactivator from the usual CDNs like unpkg:\n\n```html\n\u003cscript src=\"https://unpkg.com/vue-reactivator\"\u003e\u003c/script\u003e\n```\n\n\u003e **Note:** While this documentation will use the `reactivator` variable name for the Reactivator mixin, fetching it from a CDN will store the mixin in the `vueReactivator` global variable to make it easier to mentally associate it with Vue.\n\n## Usage\n\nSince Reactivator is really just a _framework_ for easy handling of global state, it doesn't do anything on its own. You need an accompanying _implementation_ for each state. A good starting point is the browser state collection from [`vue-browser-state`](https://github.com/Loilo/vue-browser-state), so we'll use those in our examples.\n\n\u003e A word on browser support: Reactivator is supported in all modern browsers. If you want to use it in older browsers like Internet Explorer, you'll have to transpile it to ES5 and include polyfills (e.g. for [`Object.entries`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)) yourself.\n\nUsing a Reactivator implementation is really quite simple:\n\n1. Import Reactivator\n2. Import the implementation\n3. Register Reactivator as a mixin\n\n---\n\nLet's see how this works with the browser viewport size example from the introduction:\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    Your browser viewport dimensions are {{ size[0] }}x{{ size[1] }} pixels.\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport reactivator from 'vue-reactivator'\nimport { viewportSize } from 'vue-browser-state'\n\nexport default {\n  mixins: [\n    reactivator({\n      size: viewportSize\n    })\n  ]\n}\n\u003c/script\u003e\n```\n\n\u003e **See it in action**\n\u003e\n\u003e You can take a look at the example above [in CodeSandbox](https://codesandbox.io/s/nn5vj1100l). Play around a little bit and resize the preview window, and you will see the numbers update immediately.\n\nNow you can access `this.size` anywhere in your component, just like a regular prop — you can use it to derive computed properties or put a watcher on it.\n\n---\n\nAs you can see in the example, `reactivator` is not _actually_ a mixin but rather a function that _returns_ a mixin based on the data it receives.\n\nThe `reactivator` function takes an object as its only parameter. The object consists of Reactivator implementations as values and the property names those implementations should be assigned to as keys.\n\n\u003e **Pro Tip:** You can write the script part from above even terser by renaming the imported `viewportSize`:\n\u003e\n\u003e ```js\n\u003e import reactivator from 'vue-reactivator'\n\u003e import { viewportSize as size } from 'vue-browser-state'\n\u003e\n\u003e export default {\n\u003e   mixins: [reactivator({ size })]\n\u003e }\n\u003e ```\n\n## Write Reactivator Implementations\n\nAs announced above, we're going to write a Reactivator implementation here. We're actually going to re-implement one from the `vue-browser-state` package: The `online` state. It simply contains `true` or `false`, depending on whether the user currently has a connection to the internet.\n\nFirst things first — here's what a Reactivator implementation looks like:\n\n```js\nconst implementation = {\n  getSsrState() { ... },\n  getInitialState() { ... },\n  listen(setState) { ... }\n}\n```\n\nThat's it! Not that complicated after all. In a nutshell: A Reactivator implementation is an object containing up to three methods. Each of those methods is useful yet optional.\n\n\u003e In the sections below, these three methods will be explained and applied to our \"online\" implementation. So let's start by just creating an empty object which will receive those methods one by one:\n\u003e\n\u003e ```js\n\u003e const online = {}\n\u003e ```\n\n### `getSsrState()`\n\nNot all information that we have in the browser is available on the server side. Therefore, this method should return a reasonable fallback value that is used during server-side rendering.\n\nIf this method is not defined, the property will be `undefined` until `getInitalState()` is called.\n\n\u003e When a user fetches a page from a server, they are usually online. (With things like PWAs in place, this is no longer necessarily the case, but it's sufficient to assume a user is online until the component is rendered and may prove us wrong.)\n\u003e\n\u003e ```js\n\u003e online.getSsrState = () =\u003e true\n\u003e ```\n\n### `getInitialState()`\n\nThis method is called inside [the `created` hook](https://vuejs.org/v2/api/#created) of our component. It should return the value our state initially has when the component is created — it therefore is the client-side equivalent of the `getSsrState` method.\n\nIf this method is not defined, the property will, again, be `undefined` until the listeners initiated in the `listen()` method provide any information.\n\n\u003e We can get the information whether a user is online from `navigator.onLine`. Therefore, our method looks as simple as this:\n\u003e\n\u003e ```js\n\u003e online.getInitialState = () =\u003e navigator.onLine\n\u003e ```\n\n### `listen(setState)`\n\nWhen the initial state has been received, Reactivator will look for and call the `listen` method.\n\nIt basically is a setup function where event listeners can be initialized. The provided `setState` parameter is a callback which can be used to update the implementation's state.\n\nThe `listen` method may return a cleanup function which will be called when the implementation is no longer attached to any components.\n\n\u003e The `online` and `offline` events on the `window` object notify about changes in the user's online state. We can implement them like this:\n\u003e\n\u003e ```js\n\u003e online.listen = setState =\u003e {\n\u003e   const onlineListener = () =\u003e setState(true)\n\u003e   const offlineListener = () =\u003e setState(false)\n\u003e\n\u003e   // Attach online/offline listeners\n\u003e   window.addEventListener('online', onlineListener)\n\u003e   window.addEventListener('offline', offlineListener)\n\u003e\n\u003e   return () =\u003e {\n\u003e     // Remove the listeners in the cleaup function\n\u003e     window.removeEventListener('online', onlineListener)\n\u003e     window.removeEventListener('offline', offlineListener)\n\u003e   }\n\u003e }\n\u003e ```\n\n---\n\nThat's it — our custom Reactivator implementation is ready to be used! Let's put that into a separate file:\n\n```js\n// online.js\n\nconst online = {\n  getSsrState: () =\u003e ...,\n  getInitialState: () =\u003e ...,\n  listen: () =\u003e ...\n}\n\nexport default online\n```\n\nNow we can include this implementation in our component:\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv\u003eYour browser is {{ online ? 'online' : 'offline' }}.\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport reactivator from 'vue-reactivator'\nimport online from './online'\n\nexport default {\n  mixins: [reactivator({ online })]\n}\n\u003c/script\u003e\n```\n\n### ES Modules for Implementations\n\nIf you've had a keen eye at the `online.js` file above, you might have noticed something: Because an implementation is _an object with three methods_, we can make use of how ES modules work to make our implementation even cleaner:\n\n```js\n// online.js\n\nexport function getSsrState() { ... }\nexport function getInitialState() { ... }\nexport function listen() { ... }\n```\n\nAnd then import it like this:\n\n```js\nimport * as online from './online'\n```\n\nFeels really natural, doesn't it?\n\n## Related\n\n- [`vue-browser-state`](https://github.com/Loilo/vue-browser-state) – Various browser-related Reactivator implementations\n\n## Credit\n\nThe Vue Reactivator icon is based on an illustration by [Vectors Market](https://www.flaticon.com/authors/vectors-market) from [www.flaticon.com](https://www.flaticon.com) (licensed under [Flaticon Basic License](https://file000.flaticon.com/downloads/license/license.pdf)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floilo%2Fvue-reactivator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floilo%2Fvue-reactivator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floilo%2Fvue-reactivator/lists"}