Skip to content
GitHubXDiscord

Counter

Same counter as the React and Solid versions. The trigger file is identical; only the component changes.

src/triggers/counter.trigger.ts
import { createTrigger } from '@triggery/core';

export const counterTrigger = createTrigger<{
  events:  { increment: void; decrement: void };
  actions: { adjust: number };
}>({
  id: 'counter',
  events: ['increment', 'decrement'],
  handler({ event, actions }) {
    actions.adjust?.(event.name === 'increment' ? 1 : -1);
  },
});
src/Counter.vue
<script setup lang="ts">
import { useAction, useEvent } from '@triggery/vue';
import { ref } from 'vue';
import { counterTrigger } from './triggers/counter.trigger';

const count = ref(0);

const inc = useEvent(counterTrigger, 'increment');
const dec = useEvent(counterTrigger, 'decrement');

useAction(counterTrigger, 'adjust', delta => {
  count.value += delta;
});
</script>

<template>
  <div>
    <button @click="dec()">−</button>
    <output>{{ count }}</output>
    <button @click="inc()">+</button>
  </div>
</template>

The Vue binding uses provide/inject for the runtime and onScopeDispose for cleanup — same lifecycle guarantees as React’s useEffect cleanup.