LiveVue
1.1
Headless Shared Props
v1.1
Use a headless LiveVue component (no v-component)
as a global state provider. Other components read shared props via useLiveVue(id).
What this example shows
defmodule MyAppWeb.SharedPropsLive do
use MyAppWeb, :live_view
@users [
%{name: "Alice", role: "Engineer"},
%{name: "Bob", role: "Designer"},
%{name: "Carol", role: "Product Manager"}
]
def render(assigns) do
~H"""
<div class="space-y-4">
<.vue
id="shared-state"
v-socket={@socket}
user={@user}
theme={@theme}
/>
<.vue
v-component="SharedProps"
v-socket={@socket}
pageTitle="Dashboard"
/>
<div class="flex gap-2">
<button phx-click="toggle_theme" class="btn btn-sm btn-outline">
Toggle theme
</button>
<button phx-click="cycle_user" class="btn btn-sm btn-outline">
Switch user
</button>
</div>
</div>
"""
end
def mount(_params, _session, socket) do
{:ok, assign(socket, theme: "light", user: hd(@users), user_index: 0)}
end
def handle_event("toggle_theme", _params, socket) do
theme = if socket.assigns.theme == "light", do: "dark", else: "light"
{:noreply, assign(socket, :theme, theme)}
end
def handle_event("cycle_user", _params, socket) do
index = rem(socket.assigns.user_index + 1, length(@users))
{:noreply, assign(socket, user: Enum.at(@users, index), user_index: index)}
end
end
How it works
1 Render a headless component with just an id
A <.vue>
without
v-component
renders nothing visually but registers its props under the given id.
In a real app, this lives in a sticky LiveView so it persists across page navigation.
<.vue id="shared-state" v-socket={@socket} user={@user} theme={@theme} />
2 Read shared props with useLiveVue(id)
Any Vue component on the page can call
useLiveVue("shared-state")
to access the headless component's props reactively. No prop drilling required.
const shared = useLiveVue("shared-state")
const user = computed(() => shared?.vue.props.user)
3 Server changes propagate automatically
When the server updates assigns on the headless component (e.g. switching user or theme),
all consumers that read via
useLiveVue()
re-render with the new values. Try toggling theme or switching users above.