An open API service indexing awesome lists of open source software.

https://github.com/privatenumber/vue-proxi

πŸ’  Tiny proxy component for Vue.js
https://github.com/privatenumber/vue-proxi

component inject parent-child provide proxy vue

Last synced: 7 months ago
JSON representation

πŸ’  Tiny proxy component for Vue.js

Awesome Lists containing this project

README

          

# Proxi

`` is a tiny proxy component. Whatever you add to it gets proxied to a target component!

## :raising_hand: Why?
- :recycle: **Uses Vue's Template API** Doesn't re-invent component communication!
- :muscle: **Provide/Inject on Steroids!** Familiar concepts, but super powered!
- :boom: **Reactive** All injected data is reactive (unlike provide/inject)!
- :hatched_chick: **Tiny** 755 B Gzipped!

## :rocket: Install
```sh
npm i vue-proxi
```

## :vertical_traffic_light: 3-step Setup
#### 1. :woman: Parent component
- Import and register `import Proxi from 'vue-proxi'`
- Insert anywhere in your template:
- ``
- _`key` is used to communicate with the Child. Use a unique string value or a `Symbol`_
#### 2. :baby: Child component
- Import the Proxi Inject mixin: `import { ProxiInject } from 'vue-proxi'`
- Register the mixin:

```js
export default {
// ...,

mixins: [
ProxiInject({
from: key, // from Step 1
props: [
// Becomes available on VM eg. `this.propName`
'propName'
// ...
]
})
]
}
```
#### 3. :white_check_mark: Done!
- The injected data is all available in `this.$$`
- `this.$$.class`: Class
- `this.$$.props`: Props _(Automatically bound to VM)_
- `this.$$.attrs`: Attributes
- _eg. `v-bind="$$.attrs"` or `v-bind="{ ...$attrs, ...$$.attrs }"`_
- `this.$$.listeners`: Event listeners _(Automatically bound to VM)_
- _eg. `v-on="$$.listeners"` or `v-on="{ ...$listeners, ...$$.listeners }"`_

## :man_teacher: Demos
Some quick demos to get you started!

Inheriting props?


When you declare a prop, it filters it out from the attributes list ($$.attrs) to be available directly on the view model (this.propName) and the props list ($$.props).

:woman: Parent:baby: Child


<proxi
:proxi-key="key"
:child-disabled="isDisabled"
:child-label="label"
/>


<label>
{{ label }}
<input
type="checkbox"
:disabled="childDisabled"
>
</label>


export default {
mixins: [
ProxiInject({
from: key,
props: [
'childDisabled',
'childLabel'
]
})
],
computed: {
label() {
return this.childLabel + ':';
}
}
};


Inheriting the class?


Both the static class and computed class are consolidated into $$.class for you to easily attach to any element.

:woman: Parent:baby: Child


<proxi
:proxi-key="key"
class="static-class"
:class="['child-class', {
disabled: isDisabled
}]"
/>


<div :class="$$.class">
Child
</div>


export default {
mixins: [
ProxiInject({ from: key })
],
};


Inheriting attrs?



  • Looking to inherit a specific attribute? Just pick it out from $$.attrs

  • Looking to inherit all attributes? Throw $$.attrs into v-bind



:woman: Parent:baby: Child


<proxi
:proxi-key="key"
:disabled="true"
/>


<div
:disabled="$$.attrs.disabled"
v-bind="$$.attrs"
>
Child
</div>


export default {
mixins: [
ProxiInject({ from: key })
],
};


Inheriting listeners?


All event listeners are in $$.listeners to throw right into v-on!

:woman: Parent:baby: Child


<proxi
:proxi-key="key"
@click="handleClick"
@custom-event="handleCustomEvent"
/>


<button v-on="$$.listeners">
Child
</button>


export default {
mixins: [
ProxiInject({ from: key })
],
mounted() {
// Listeners are automatically bound to VM
this.$emit('custom-event', 'Mounted!');
}
};


### Advanced
This demo shows how a parent-child pair, RadioGroup and Radio, communicate using Proxi. Note how the two components only come together at usage.

[![JSFiddle Demo](https://flat.badgen.net/badge/JSFiddle/Open%20Demo/blue)](https://jsfiddle.net/hirokiosame/akwfm1sp/)

Usage

```vue








Selected: {{ selected }}

export default {
data() {
return {
selected: []
}
}
}

```

Parent: RadioGroup.vue

```vue





import Proxi from 'vue-proxi'

export default {
components: {
Proxi
},

props: ['value'],

data() {
return {
// Same idea as provide/inject
// Use a Symbol for security
key: 'radios'
}
}
}

```

Child: Radio.vue

```vue



{{ label }}

import { ProxiInject } from 'vue-proxi'

export default {
mixins: [
ProxiInject({
// Same key as parent
from: 'radios',

// Declare props that can be injected in
// Only array supported for now
props: ['checkedItems']
})
],

props: {
label: String,
value: null
},

computed: {
isChecked() {
return this.checkedItems.includes(this.value)
}
},

methods: {
onClick() {
if (this.isChecked) {
this.$emit('update', this.checkedItems.filter(i => i !== this.value))
} else {
this.$emit('update', [...this.checkedItems, this.value])
}
}
}
}

```

## :family: Related
- [vue-subslot](https://github.com/privatenumber/vue-subslot) - πŸ’ Pick 'n choose what you want from a slot passed into your Vue component
- [vue-pseudo-window](https://github.com/privatenumber/vue-pseudo-window) - πŸ–Ό Declaratively interface window/document in your Vue template
- [vue-vnode-syringe](https://github.com/privatenumber/vue-vnode-syringe) - 🧬Mutate your vNodes with vNode Syringe πŸ’‰