Store-Mediated Siblings

Two independent components coordinating through a shared store.

Live Demo

Two independent components (the cart manager and the cart badge) both subscribe to the same store.

Product List
items in cart

Source

HTML + JavaScript
<!-- Two sibling components, no parent-child relationship -->
<div data-component="product-list">
    <div data-list="products">
        <template>
            <div>
                <span data-bind="productName"></span>
                <button data-action="addToCart">Add</button>
            </div>
        </template>
    </div>
</div>

<div data-component="cart-badge">
    <span data-bind="itemCount"></span> items
    <span data-bind="totalLabel"></span>
    <button data-action="clearCart">Clear</button>
</div>

<script>
// Shared store: both components subscribe
wildflower.store('cart', {
    state: { items: [] },
    addItem(product) {
        this.items.push(product);
    },
    clear() { this.items = []; }
});

wildflower.component('product-list', {
    state: {
        products: [
            { productName: 'Widget', price: 9.99 },
            { productName: 'Gadget', price: 24.99 },
            { productName: 'Doohickey', price: 14.99 }
        ]
    },
    addToCart(e, el, { index }) {
        wildflower.getStore('cart').addItem(this.products[index]);
    }
});

wildflower.component('cart-badge', {
    subscribe: { cart: ['items'] },
    computed: {
        itemCount() { return this.stores.cart?.items?.length || 0; },
        totalLabel() {
            const sum = (this.stores.cart?.items || [])
                .reduce((t, i) => t + i.price, 0);
            return '$' + sum.toFixed(2);
        }
    },
    clearCart() { wildflower.getStore('cart').clear(); }
});
</script>

Key Points

  • wildflower.store('cart', ...) creates shared state. Neither component owns it
  • subscribe: { cart: ['items'] } tells the cart-badge to re-render when the store's items changes
  • The product list calls wildflower.getStore('cart').addItem(). Store methods are accessed globally
  • The cart badge reads store state via this.stores.cart.items in computed properties
  • No event wiring, no prop drilling. The store is the single coordination point