1.0.1 • Published 12 months ago

vue-proxi v1.0.1

Weekly downloads
3
License
MIT
Repository
github
Last release
12 months ago

Proxi

<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

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:
    • <proxi :proxi-key="key" [... attr / :prop / @listener]>
    • 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:
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!

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

<template>
    <div>
        <radio-group v-model="selected">
            <radio
                label="Apples"
                value="apples"
            />
            <radio
                label="Oranges"
                value="oranges"
            />
            <radio
                label="Bananas"
                value="bananas"
            />
        </radio-group>
        <div>
            Selected: {{ selected }}
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            selected: []
        }
    }
}
</script>
<template>
    <div>
        <proxi
            :proxi-key="key"
            :checked-items="value"
            @update="$emit('input', $event)"
        >
            <slot />
        </proxi>
    </div>
</template>

<script>
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'
        }
    }
}
</script>
<template>
    <label>
        <input
            type="checkbox"
            :checked="isChecked"
            @click="onClick"
        >
        {{ label }}
    </label>
</template>

<script>
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])
            }
        }
    }
}
</script>

:family: Related

  • vue-subslot - 💍 Pick 'n choose what you want from a slot passed into your Vue component
  • vue-pseudo-window - 🖼 Declaratively interface window/document in your Vue template
  • vue-vnode-syringe - 🧬Mutate your vNodes with vNode Syringe 💉