If you wish to write single-file Vue components, you'll need to work with the Vue compiler somehow - this library does not cover that.
However, with the standard Phoenix ESBuild setup, it's easily done by:
- Following the instructions in the Phoenix docs for using esbuild plugins
- Adding a Vue ESBuild plugin such as esbuild-plugin-vue3
- Adding
vue
as a dependency to your assetsnpm install vue --prefix assets
If you are only using Vue components as opposed to writing your own, you should be able to skip this step.
-
Follow the instructions from the phx_frontend library to render js apps with Phoenix Liveview.
-
Add the npm dependency
phx-frontend-vue
in theassets
folder, e.g.
npm install --save phx-frontend-vue --prefix assets
If we have a Vue Counter
component that we would normally use in Vue like so
<Counter
:counter="4"
@inc="(amount) => console.log(`Increment by ${amount}`)"
/>
then we can render it from a LiveView with
def render(assigns) do
~H"""
<.js_app
id="my-counter"
component="Counter"
props={%{counter: @counter}}
callbacks={%{inc: "increment"}}
/>
"""
end
def handle_event("increment", %{amount: amount}, socket) do
IO.puts("Increment by #{amount}")
{:noreply, socket}
end
To do the above you need configure the hook in your app.js
like so:
// ...
import { createJsApps } from "phx-frontend";
+import createVueApp from "phx-frontend-vue";
+import Counter from "path/to/vue/counter/component.vue";
// ...
let liveSocket = new LiveSocket("/live", Socket, {
// ...
hooks: {
// ...
jsApp: createJsApps({
// ...
+ Counter: createVueApp(Counter, {
+ // not needed if you don't need to map callback params
+ callbackParams: {
+ inc: (amount) => ({ amount }),
+ },
+ }),
}),
},
});
// ...
If you don't map callbackParams
then handle_event
will be called with an empty map %{}
.
In that case you can omit the options arg to createVueApp in app.js
:
Counter: createVueApp(Counter);