AbsoluteJS

Vue Islands

Vue hosts can use the loose Island export or a typed wrapper from createTypedIsland(registry) when they want exact registry-driven inference.

#Authoring

Typed Vue islands infer the full prop object from the target component. The built-in Island remains available when you want a looser API.

VUE
<script setup lang="ts">
import { Island } from '@absolutejs/absolute/vue';
import { TypedVueIsland } from '../../islands/registry';
</script>

<template>
  <main>
    <TypedVueIsland
      framework="react"
      component="ReactCounter"
      :props="{ initialCount: 0, label: 'React island' }"
      hydrate="load"
    />

    <Island
      framework="vue"
      component="VueCounter"
      :props="{ initialCount: 0, label: 'Loose deferred Vue island' }"
      hydrate="visible"
    />
  </main>
</template>

#Stores

Vue islands read and react to shared state through useIslandStore, which returns a Vue Ref over the shared Zustand-backed store.

TS
import { defineComponent, h, ref } from 'vue';
import { useIslandStore } from '@absolutejs/absolute/vue';
import { counterIslandStore } from '../../islands/counterStore';

export const VueCounter = defineComponent({
  props: {
    initialCount: { type: Number, required: true },
    label: { type: String, required: true }
  },
  setup(props) {
    const count = ref(props.initialCount);
    const sharedCount = useIslandStore(
      counterIslandStore,
      (state) => state.sharedCount
    );
    const incrementShared = useIslandStore(
      counterIslandStore,
      (state) => state.incrementShared
    );

    return () =>
      h('div', [
        h('p', props.label),
        h('strong', 'Local: ' + String(count.value)),
        h('strong', 'Shared: ' + String(sharedCount.value)),
        h('button', { onClick: () => { count.value += 1; } }, 'Increment Vue'),
        h('button', { onClick: () => { incrementShared.value(); } }, 'Increment Shared')
      ]);
  }
});