LiveVue
1.0
Counter
The classic counter example demonstrating the core LiveVue pattern: server state flows down as props, user interactions bubble up as events.
What this example shows
<script setup lang="ts">
import { ref } from "vue"
const props = defineProps<{ count: number }>()
const diff = ref(1)
</script>
<template>
<div class="card bg-base-200 p-6">
<div class="text-center mb-6">
<div class="text-sm text-neutral mb-2">Count</div>
<Transition name="count" mode="out-in">
<div :key="props.count" class="text-5xl font-mono font-bold">
{{ props.count }}
</div>
</Transition>
</div>
<div class="mb-6">
<label class="flex justify-between text-sm text-neutral mb-2">
<span>Step</span>
<span class="font-mono text-primary">{{ diff }}</span>
</label>
<input
v-model.number="diff"
type="range"
min="1"
max="10"
class="range range-primary range-sm"
/>
</div>
<div class="flex gap-2">
<button phx-click="inc" :phx-value-diff="-diff" class="btn btn-outline flex-1">
−{{ diff }}
</button>
<button phx-click="inc" :phx-value-diff="diff" class="btn btn-secondary flex-1">
+{{ diff }}
</button>
<button phx-click="reset" class="btn btn-ghost text-neutral">
Reset
</button>
</div>
</div>
</template>
<style scoped>
.count-enter-active,
.count-leave-active {
transition: all 0.15s ease;
}
.count-enter-from {
opacity: 0;
transform: translateY(-8px);
}
.count-leave-to {
opacity: 0;
transform: translateY(8px);
}
</style>
How it works
1 Props flow from LiveView to Vue
The count
assign in LiveView
becomes a prop in Vue. When the server state changes, Vue automatically re-renders with the new value.
<.vue count={@count} v-component="Counter" v-socket={@socket} />
2 Local state stays in Vue
The diff
slider value is managed entirely in Vue
using ref(). No server round-trip for UI-only state.
const diff = ref(1) // Local Vue state
3 Phoenix bindings work in Vue templates
Standard Phoenix event bindings like
phx-click
work directly in Vue templates. Use Vue's
:phx-value-*
binding
to pass dynamic values.
<button phx-click="inc" :phx-value-diff="diff">+{{ diff }}</button>
4 Vue transitions on server updates
Vue's <Transition>
component animates when props change from the server. The
:key
binding triggers the transition on each value change.
<Transition name="count" mode="out-in">
<div :key="props.count">{{ props.count }}</div>
</Transition>