{"id":16347798,"url":"https://github.com/privatenumber/vue-pseudo-window","last_synced_at":"2025-03-21T00:30:22.729Z","repository":{"id":54618589,"uuid":"152992013","full_name":"privatenumber/vue-pseudo-window","owner":"privatenumber","description":"🖼 Declaratively interface window/document/body in your Vue template","archived":false,"fork":false,"pushed_at":"2021-03-14T07:51:36.000Z","size":903,"stargazers_count":31,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2024-05-04T00:17:54.245Z","etag":null,"topics":["declarative","document","event-handling","event-listeners","html","vue","window"],"latest_commit_sha":null,"homepage":"","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/privatenumber.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}},"created_at":"2018-10-14T15:59:50.000Z","updated_at":"2023-04-08T13:36:05.000Z","dependencies_parsed_at":"2022-08-13T21:40:54.546Z","dependency_job_id":null,"html_url":"https://github.com/privatenumber/vue-pseudo-window","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/privatenumber%2Fvue-pseudo-window","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-pseudo-window/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-pseudo-window/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-pseudo-window/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/privatenumber","download_url":"https://codeload.github.com/privatenumber/vue-pseudo-window/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244094204,"owners_count":20397020,"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":["declarative","document","event-handling","event-listeners","html","vue","window"],"created_at":"2024-10-11T00:46:06.458Z","updated_at":"2025-03-21T00:30:22.389Z","avatar_url":"https://github.com/privatenumber.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Components \u0026 Libraries","UI Utilities [🔝](#readme)"],"sub_categories":["UI Utilities"],"readme":"# 🖼 Pseudo Window \u003ca href=\"https://npm.im/vue-pseudo-window\"\u003e\u003cimg src=\"https://badgen.net/npm/v/vue-pseudo-window\"\u003e\u003c/a\u003e \u003ca href=\"https://npm.im/vue-pseudo-window\"\u003e\u003cimg src=\"https://badgen.net/npm/dm/vue-pseudo-window\"\u003e\u003c/a\u003e \u003ca href=\"https://packagephobia.now.sh/result?p=vue-pseudo-window\"\u003e\u003cimg src=\"https://packagephobia.now.sh/badge?p=vue-pseudo-window\"\u003e\u003c/a\u003e \u003ca href=\"https://bundlephobia.com/result?p=vue-pseudo-window\"\u003e\u003cimg src=\"https://badgen.net/bundlephobia/minzip/vue-pseudo-window\"\u003e\u003c/a\u003e\n\nVue component to bind event-handlers or classes to `window`/`document`/`body`!\n\nInsert pseudo-window anywhere in your template:\n```html\n\u003cpseudo-window @resize.passive=\"handleResize\" /\u003e\n```\n\n👉 Try out a [demo in this CodePen](https://codepen.io/privatenumber/pen/qBqEOGa)!\n\n## 🚀 Install\n```sh\nnpm i vue-pseudo-window\n```\n## 🙋‍♂️ Why?\n\n- ✨ **Cleaner code** No longer pollute your component with `.addEventListener()` \u0026 `.removeEventListener()`\n- ♻️ **Template API** Use Vue's `@event` syntax to bind listeners to the window as like you would to any other element\n- 💪 **Robust** Supports all event modifiers `capture`, `passive`, and `once`. SSR friendly.\n- 🐥 **Tiny** 819 B Gzipped!\n\n### Before\n```html\n\u003ctemplate\u003e\n  ...\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n\n\t// Your component would be polluted with event binding logic\n\tmounted() {\n\t\twindow.addEventListener('resize', this.handleResize, { passive: true })\n\t},\n\n\tbeforeDestroy() {\n\t\twindow.removeEventListener('resize', this.handleResize)\n\t},\n\n\tmethods: {\n\t\thandleResize() {\n\t\t\t...\n\t\t}\n\t}\n}\n\u003c/script\u003e\n```\n\n### After \u003csup\u003e✨\u003c/sup\u003e\n\n```html\n\u003ctemplate\u003e\n\t\u003cdiv\u003e\n\t\t...\n\n\t\t\u003c!-- Insert pseudo-window anywhere in your template --\u003e\n\t\t\u003cpseudo-window @resize.passive=\"handleResize\" /\u003e\n\t\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n\n\t// Much cleaner!\n\tmethods: {\n\t\thandleResize() {\n\t\t\t...\n\t\t}\n\t}\n}\n\u003c/script\u003e\n```\n\n## 👨‍🏫 Demos [![JSFiddle Demo](https://flat.badgen.net/badge/JSFiddle/Open%20Demo/blue)](https://jsfiddle.net/hirokiosame/p5Lz419s/)\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eAdding listeners to \u003ccode\u003ewindow\u003c/code\u003e\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\n```html\n\u003ctemplate\u003e\n\t\u003cdiv\u003e\n\t\t\u003cdiv\u003e\n\t\t\tWindow width: {{ winWidth }}\n\t\t\u003c/div\u003e\n\n\t\t\u003cpseudo-window\n\t\t\t\u003c!-- Handle window resize with \"passive\" option --\u003e\n\t\t\t@resize.passive=\"onResize\"\n\t\t/\u003e\n\t\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport PseudoWindow from 'vue-pseudo-window';\n\nexport default {\n\tcomponents: {\n\t\tPseudoWindow\n\t},\n\t\n\tdata() {\n\t\treturn {\n\t\t\twinWidth: 0\n\t\t}\n\t},\n\n\tmethods: {\n\t\tonResize() {\n\t\t\tthis.winWidth = window.innerWidth;\n\t\t}\n\t}\n}\n\u003c/script\u003e\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eAdding class \u0026 listeners to \u003ccode\u003edocument \u0026lt;html\u0026gt;\u003c/code\u003e\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\n```html\n\u003ctemplate\u003e\n\t\u003cdiv\u003e\n\t\t\u003cpseudo-window\n\t\t\tdocument\n\n\t\t\t\u003c!-- Add a class to \u003chtml\u003e --\u003e\n\t\t\t:class=\"$style.lockScroll\"\n\n\t\t\t\u003c!-- Handle document click --\u003e\n\t\t\t@click=\"onClick\"\n\t\t/\u003e\n\t\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport PseudoWindow from 'vue-pseudo-window';\n\nexport default {\n\tcomponents: {\n\t\tPseudoWindow\n\t},\n\n\tmethods: {\n\t\tonClick() {\n\t\t\tconsole.log('Document click!')\n\t\t}\n\t}\n}\n\u003c/script\u003e\n\n\u003cstyle module\u003e\n.lockScroll {\n\toverflow: hidden;\n}\n\u003c/style\u003e\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eAdding class \u0026 listeners to \u003ccode\u003ebody \u0026lt;body\u0026gt;\u003c/code\u003e\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\n```html\n\u003ctemplate\u003e\n\t\u003cdiv\u003e\n\t\t\u003cpseudo-window\n\t\t\tbody\n\n\t\t\t\u003c!-- Add a class to \u003cbody\u003e --\u003e\n\t\t\t:class=\"$style.lockScroll\"\n\n\t\t\t\u003c!-- Handle body click --\u003e\n\t\t\t@click=\"onClick\"\n\t\t/\u003e\n\t\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport PseudoWindow from 'vue-pseudo-window';\n\nexport default {\n\tcomponents: {\n\t\tPseudoWindow\n\t},\n\n\tmethods: {\n\t\tonClick() {\n\t\t\tconsole.log('Body click!')\n\t\t}\n\t}\n}\n\u003c/script\u003e\n\n\u003cstyle module\u003e\n.lockScroll {\n\toverflow: hidden;\n}\n\u003c/style\u003e\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eOnly want one root element?\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\t\nPseudoWindow is a functional component that returns exactly what's passed into it. By using it as the root component, its contents will pass-through.\n\n```html\n\u003ctemplate\u003e\n\t\u003cpseudo-window\n\t\t@blur=\"pause\"\n\t\t@focus=\"resume\"\n\t\u003e\n\t\t\u003cvideo\u003e\n\t\t\t\u003csource\n\t\t\t\tsrc=\"/media/examples/flower.webm\"\n\t\t\t\ttype=\"video/webm\"\n\t\t\t\u003e\n\t\t\u003c/video\u003e\n\t\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport PseudoWindow from 'vue-pseudo-window';\n\nexport default {\n\tcomponents: {\n\t\tPseudoWindow\n\t},\n\n\tmethods: {\n\t\tresume() {\n\t\t\tthis.$el.play()\n\t\t},\n\t\tpause() {\n\t\t\tthis.$el.pause()\n\t\t}\n\t}\n}\n\u003c/script\u003e\n```\n\u003c/details\u003e\n\n## 👨‍👩‍👧‍👦 Related\n- [vue-subslot](https://github.com/privatenumber/vue-subslot) - 💍 Pick 'n choose what you want from a slot passed into your Vue component\n- [vue-proxi](https://github.com/privatenumber/vue-proxi) - 💠 Tiny proxy component for Vue.js\n- [vue-vnode-syringe](https://github.com/privatenumber/vue-vnode-syringe) - 🧬Mutate your vNodes with vNode Syringe 💉\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprivatenumber%2Fvue-pseudo-window","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprivatenumber%2Fvue-pseudo-window","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprivatenumber%2Fvue-pseudo-window/lists"}