{"id":16347509,"url":"https://github.com/privatenumber/vue-proxi","last_synced_at":"2025-03-21T00:30:23.903Z","repository":{"id":54234811,"uuid":"256085496","full_name":"privatenumber/vue-proxi","owner":"privatenumber","description":"💠 Tiny proxy component for Vue.js","archived":false,"fork":false,"pushed_at":"2023-05-18T05:28:47.000Z","size":390,"stargazers_count":15,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2025-03-09T13:22:39.374Z","etag":null,"topics":["component","inject","parent-child","provide","proxy","vue"],"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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"privatenumber"}},"created_at":"2020-04-16T02:08:56.000Z","updated_at":"2024-08-13T23:56:05.000Z","dependencies_parsed_at":"2024-10-24T21:27:25.757Z","dependency_job_id":"61ce947c-2065-4d1c-914e-e707fc11a06d","html_url":"https://github.com/privatenumber/vue-proxi","commit_stats":{"total_commits":76,"total_committers":3,"mean_commits":"25.333333333333332","dds":0.06578947368421051,"last_synced_commit":"21fdbdeb56fbbd98b3ec6b4290a1ff8399e1e39b"},"previous_names":["privatenumber/vue-voodoo-doll"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-proxi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-proxi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-proxi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/privatenumber%2Fvue-proxi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/privatenumber","download_url":"https://codeload.github.com/privatenumber/vue-proxi/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244092769,"owners_count":20396868,"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":["component","inject","parent-child","provide","proxy","vue"],"created_at":"2024-10-11T00:43:08.547Z","updated_at":"2025-03-21T00:30:23.567Z","avatar_url":"https://github.com/privatenumber.png","language":"JavaScript","funding_links":["https://github.com/sponsors/privatenumber"],"categories":[],"sub_categories":[],"readme":"# Proxi \u003ca href=\"https://npm.im/vue-proxi\"\u003e\u003cimg src=\"https://badgen.net/npm/v/vue-proxi\"\u003e\u003c/a\u003e \u003ca href=\"https://npm.im/vue-proxi\"\u003e\u003cimg src=\"https://badgen.net/npm/dm/vue-proxi\"\u003e\u003c/a\u003e \u003ca href=\"https://packagephobia.now.sh/result?p=vue-proxi\"\u003e\u003cimg src=\"https://packagephobia.now.sh/badge?p=vue-proxi\"\u003e\u003c/a\u003e \u003ca href=\"https://bundlephobia.com/result?p=vue-proxi\"\u003e\u003cimg src=\"https://badgen.net/bundlephobia/minzip/vue-proxi\"\u003e\u003c/a\u003e\n\n`\u003cproxi\u003e` is a tiny proxy component. Whatever you add to it gets proxied to a target component!\n\n## :raising_hand: Why?\n- :recycle: **Uses Vue's Template API** Doesn't re-invent component communication!\n- :muscle: **Provide/Inject on Steroids!** Familiar concepts, but super powered!\n- :boom: **Reactive** All injected data is reactive (unlike provide/inject)!\n- :hatched_chick: **Tiny** 755 B Gzipped!\n\n## :rocket: Install\n```sh\nnpm i vue-proxi\n```\n\n## :vertical_traffic_light: 3-step Setup\n#### 1. :woman: Parent component\n   - Import and register `import Proxi from 'vue-proxi'`\n   - Insert anywhere in your template:\n      - `\u003cproxi :proxi-key=\"key\" [... attr / :prop / @listener]\u003e`\n      - _`key` is used to communicate with the Child. Use a unique string value or a `Symbol`_\n#### 2. :baby: Child component\n   - Import the Proxi Inject mixin: `import { ProxiInject } from 'vue-proxi'`\n   - Register the mixin:\n\n```js\nexport default {\n    // ...,\n\n    mixins: [\n        ProxiInject({\n            from: key, // from Step 1\n            props: [\n                // Becomes available on VM eg. `this.propName`\n                'propName'\n                // ...\n            ]\n        })\n    ]\n}\n```\n#### 3. :white_check_mark: Done!\n   - The injected data is all available in `this.$$`\n     - `this.$$.class`: Class\n     - `this.$$.props`: Props _(Automatically bound to VM)_\n     - `this.$$.attrs`: Attributes\n       - _eg. `v-bind=\"$$.attrs\"` or `v-bind=\"{ ...$attrs, ...$$.attrs }\"`_\n     - `this.$$.listeners`: Event listeners _(Automatically bound to VM)_\n       - _eg. `v-on=\"$$.listeners\"` or `v-on=\"{ ...$listeners, ...$$.listeners }\"`_\n\n## :man_teacher: Demos\nSome quick demos to get you started!\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eInheriting props?\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\tWhen you declare a prop, it filters it out from the attributes list (\u003ccode\u003e$$.attrs\u003c/code\u003e) to be available directly on the view model (\u003ccode\u003ethis.propName\u003c/code\u003e) and the props list (\u003ccode\u003e$$.props\u003c/code\u003e).\n\t\u003ctable\u003e\n\t\t\u003ctr\u003e\u003cth\u003e:woman: Parent\u003c/th\u003e\u003cth\u003e:baby: Child\u003c/th\u003e\u003c/tr\u003e\n\t\t\u003ctr\u003e\n\t\t\t\u003ctd valign=\"top\"\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;proxi\n    :proxi-key=\"key\"\n    :child-disabled=\"isDisabled\"\n    :child-label=\"label\"\n/\u0026gt;\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\t\u003ctd\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;label\u0026gt;\n    {{ label }}\n    \u0026lt;input\n        type=\"checkbox\"\n        :disabled=\"childDisabled\"\n    \u0026gt;\n\u0026lt;/label\u0026gt;\n\u003c/pre\u003e\u003chr\u003e\u003cpre lang=\"js\"\u003e\nexport default {\n  mixins: [\n    ProxiInject({\n      from: key,\n      props: [\n        'childDisabled',\n        'childLabel'\n      ]\n    })\n  ],\n  computed: {\n    label() {\n      return this.childLabel + ':';\n    }\n  }\n};\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\u003c/tr\u003e\n\t\u003c/table\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eInheriting the class?\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\tBoth the static class and computed class are consolidated into \u003ccode\u003e$$.class\u003c/code\u003e for you to easily attach to any element.\n\t\u003ctable\u003e\n\t\t\u003ctr\u003e\u003cth\u003e:woman: Parent\u003c/th\u003e\u003cth\u003e:baby: Child\u003c/th\u003e\u003c/tr\u003e\n\t\t\u003ctr\u003e\n\t\t\t\u003ctd valign=\"top\"\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;proxi\n    :proxi-key=\"key\"\n    class=\"static-class\"\n    :class=\"['child-class', {\n        disabled: isDisabled\n    }]\"\n/\u0026gt;\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\t\u003ctd\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;div :class=\"$$.class\"\u0026gt;\n    Child\n\u0026lt;/div\u0026gt;\n\u003c/pre\u003e\u003chr\u003e\u003cpre lang=\"js\"\u003e\nexport default {\n    mixins: [\n        ProxiInject({ from: key })\n    ],\n};\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\u003c/tr\u003e\n\t\u003c/table\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eInheriting attrs?\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\t\u003cul\u003e\n\t\t\u003cli\u003eLooking to inherit a specific attribute? Just pick it out from \u003ccode\u003e$$.attrs\u003c/code\u003e\u003c/li\u003e\n\t\t\u003cli\u003eLooking to inherit all attributes? Throw \u003ccode\u003e$$.attrs\u003c/code\u003e into \u003ccode\u003ev-bind\u003c/code\u003e\u003c/li\u003e\n\t\u003c/ul\u003e\n\t\u003ctable\u003e\n\t\t\u003ctr\u003e\u003cth\u003e:woman: Parent\u003c/th\u003e\u003cth\u003e:baby: Child\u003c/th\u003e\u003c/tr\u003e\n\t\t\u003ctr\u003e\n\t\t\t\u003ctd valign=\"top\"\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;proxi\n    :proxi-key=\"key\"\n    :disabled=\"true\"\n/\u0026gt;\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\t\u003ctd\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;div\n    :disabled=\"$$.attrs.disabled\"\n    v-bind=\"$$.attrs\"\n\u0026gt;\n    Child\n\u0026lt;/div\u0026gt;\n\u003c/pre\u003e\u003chr\u003e\u003cpre lang=\"js\"\u003e\nexport default {\n    mixins: [\n        ProxiInject({ from: key })\n    ],\n};\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\u003c/tr\u003e\n\t\u003c/table\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003e\u003cstrong\u003eInheriting listeners?\u003c/strong\u003e\u003c/summary\u003e\n\t\u003cbr\u003e\n\tAll event listeners are in \u003ccode\u003e$$.listeners\u003c/code\u003e to throw right into \u003ccode\u003ev-on\u003c/code\u003e!\n\t\u003ctable\u003e\n\t\t\u003ctr\u003e\u003cth\u003e:woman: Parent\u003c/th\u003e\u003cth\u003e:baby: Child\u003c/th\u003e\u003c/tr\u003e\n\t\t\u003ctr\u003e\n\t\t\t\u003ctd valign=\"top\"\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;proxi\n    :proxi-key=\"key\"\n    @click=\"handleClick\"\n    @custom-event=\"handleCustomEvent\"\n/\u0026gt;\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\t\u003ctd\u003e\u003cpre lang=\"html\"\u003e\n\u0026lt;button v-on=\"$$.listeners\"\u0026gt;\n    Child\n\u0026lt;/button\u0026gt;\n\u003c/pre\u003e\u003chr\u003e\u003cpre lang=\"js\"\u003e\nexport default {\n    mixins: [\n        ProxiInject({ from: key })\n    ],\n    mounted() {\n        // Listeners are automatically bound to VM\n        this.$emit('custom-event', 'Mounted!');\n    }\n};\n\u003c/pre\u003e\u003c/td\u003e\n\t\t\u003c/tr\u003e\n\t\u003c/table\u003e\n\u003c/details\u003e\n\n\n### Advanced\nThis demo shows how a parent-child pair, RadioGroup and Radio, communicate using Proxi. Note how the two components only come together at usage.\n\n[![JSFiddle Demo](https://flat.badgen.net/badge/JSFiddle/Open%20Demo/blue)](https://jsfiddle.net/hirokiosame/akwfm1sp/)\n\n\u003cdetails\u003e\n\t\u003csummary\u003eUsage\u003c/summary\u003e\n\n```vue\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        \u003cradio-group v-model=\"selected\"\u003e\n            \u003cradio\n                label=\"Apples\"\n                value=\"apples\"\n            /\u003e\n            \u003cradio\n                label=\"Oranges\"\n                value=\"oranges\"\n            /\u003e\n            \u003cradio\n                label=\"Bananas\"\n                value=\"bananas\"\n            /\u003e\n        \u003c/radio-group\u003e\n        \u003cdiv\u003e\n            Selected: {{ selected }}\n        \u003c/div\u003e\n    \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n    data() {\n        return {\n            selected: []\n        }\n    }\n}\n\u003c/script\u003e\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003eParent: \u003ci\u003eRadioGroup.vue\u003c/i\u003e\u003c/summary\u003e\n\n```vue\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        \u003cproxi\n            :proxi-key=\"key\"\n            :checked-items=\"value\"\n            @update=\"$emit('input', $event)\"\n        \u003e\n            \u003cslot /\u003e\n        \u003c/proxi\u003e\n    \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport Proxi from 'vue-proxi'\n\nexport default {\n    components: {\n        Proxi\n    },\n\n    props: ['value'],\n\n    data() {\n        return {\n            // Same idea as provide/inject\n            // Use a Symbol for security\n            key: 'radios'\n        }\n    }\n}\n\u003c/script\u003e\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\t\u003csummary\u003eChild: \u003ci\u003eRadio.vue\u003c/i\u003e\u003c/summary\u003e\n\n\n```vue\n\u003ctemplate\u003e\n    \u003clabel\u003e\n        \u003cinput\n            type=\"checkbox\"\n            :checked=\"isChecked\"\n            @click=\"onClick\"\n        \u003e\n        {{ label }}\n    \u003c/label\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport { ProxiInject } from 'vue-proxi'\n\nexport default {\n    mixins: [\n        ProxiInject({\n            // Same key as parent\n            from: 'radios',\n\n            // Declare props that can be injected in\n            // Only array supported for now\n            props: ['checkedItems']\n        })\n    ],\n\n    props: {\n        label: String,\n        value: null\n    },\n\n    computed: {\n        isChecked() {\n            return this.checkedItems.includes(this.value)\n        }\n    },\n\n    methods: {\n        onClick() {\n            if (this.isChecked) {\n                this.$emit('update', this.checkedItems.filter(i =\u003e i !== this.value))\n            } else {\n                this.$emit('update', [...this.checkedItems, this.value])\n            }\n        }\n    }\n}\n\u003c/script\u003e\n```\n\u003c/details\u003e\n\n\n## :family: 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-pseudo-window](https://github.com/privatenumber/vue-pseudo-window) - 🖼 Declaratively interface window/document in your Vue template\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-proxi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprivatenumber%2Fvue-proxi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprivatenumber%2Fvue-proxi/lists"}