### Setup and Start Phoenix Server Source: https://github.com/valian/live_vue/blob/main/example_project/README.md Instructions for setting up dependencies and starting the Phoenix server for the LiveVueExamples project. This involves running mix setup and then starting the Phoenix endpoint. ```bash mix setup mix phx.server ``` -------------------------------- ### Run Example Project Server Source: https://github.com/valian/live_vue/blob/main/CLAUDE.md Starts the Phoenix server for the example project, allowing developers to test LiveVue features in a live environment. Changes in the parent library are reflected immediately. ```bash cd example_project mix phx.server # Visit http://localhost:4000 ``` -------------------------------- ### Create New Phoenix Project with LiveVue (Mix) Source: https://github.com/valian/live_vue/blob/main/guides/installation.md This Mix command creates a new Phoenix project pre-configured with LiveVue, Vite, Vue, and TypeScript. It automates the setup process for a seamless developer experience. Requires Igniter to be installed. ```mix mix igniter.new my_app --with phx.new --install live_vue ``` -------------------------------- ### Basic LiveVue Application Setup (JavaScript) Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Initializes the Vue application using `createLiveVue` in `assets/vue/index.js`. This snippet defines essential `resolve` and `setup` functions. The `resolve` function handles component loading, and the `setup` function configures the Vue app instance, including plugins and mounting. ```javascript import "vite/modulepreload-polyfill" import { h } from "vue" import { createLiveVue, findComponent } from "live_vue" export default createLiveVue({ // Component resolution - adjust this to your needs // Eg. You might want to import some components directly from node_modules // or lazy load components resolve: name => { const components = { ...import.meta.glob("./**/*.vue", { eager: true }), ...import.meta.glob("../../lib/**/*.vue", { eager: true }), } // findComponent resolves the component based on suffix. // Equivalent to this snippet + some error handling: // for (const [key, value] of Object.entries(components)) { // if (key.endsWith(`${name}.vue`) || key.endsWith(`${name}/index.vue`)) { // return value // } // } return findComponent(components, name) }, // Vue app setup setup: ({ createApp, component, props, slots, plugin, el }) => { const app = createApp({ render: () => h(component, props, slots) }) app.use(plugin) app.mount(el) return app }, }) ``` -------------------------------- ### Setup Project Dependencies Source: https://github.com/valian/live_vue/blob/main/CLAUDE.md Installs project dependencies and builds assets for the first time, preparing the development environment. ```bash mix setup ``` -------------------------------- ### Install Igniter Archive (Bash) Source: https://github.com/valian/live_vue/blob/main/guides/installation.md This command installs the Igniter archive, a tool used for scaffolding and managing Phoenix projects with LiveVue integration. Ensure you have Elixir and Mix installed. ```bash mix archive.install hex igniter_new ``` -------------------------------- ### Install LiveVue in Existing Project (Mix) Source: https://github.com/valian/live_vue/blob/main/guides/installation.md This Mix command adds LiveVue version 1.0.0-rc.3 to an existing Phoenix 1.8+ project, automatically configuring necessary settings. Ensure your project meets the Phoenix 1.8+ prerequisite. ```mix mix igniter.install live_vue@1.0.0-rc.3 ``` -------------------------------- ### Install Node.js on Custom Server Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Installs Node.js version 19 or later on a custom server environment using a script from NodeSource. This is essential for deploying LiveVue applications on bare metal or VM deployments. ```bash curl -fsSL https://deb.nodesource.com/setup_19.x | bash - apt-get install -y nodejs ``` -------------------------------- ### Example Vue Component Using Shared Props - Vue Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md An example Vue component demonstrating how to receive and use shared props that are automatically injected by LiveVue. Props like `flash`, `user`, and `locale` are directly available without explicit definition in `defineProps`. ```vue ``` -------------------------------- ### Customize Vue App with Plugins and Stores Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Demonstrates how to set up a Vue application using createLiveVue, including adding essential plugins like Pinia for state management and Vue-i18n for internationalization. It also shows how to handle server-side rendering specific setups. ```javascript import { createPinia } from "pinia" import { createI18n } from "vue-i18n" export default createLiveVue({ setup: ({ createApp, component, props, slots, plugin, el, ssr }) => { const app = createApp({ render: () => h(component, props, slots) }) // LiveVue plugin (required) app.use(plugin) // Add your plugins const pinia = createPinia() app.use(pinia) const i18n = createI18n({ locale: 'en', messages: { /* your translations */ } }) app.use(i18n) // SSR-specific setup if (ssr) { // Server-side specific initialization } app.mount(el) return app } }) ``` -------------------------------- ### LiveVue Encoder Protocol for Custom Structs Source: https://github.com/valian/live_vue/blob/main/guides/getting_started.md Example of implementing the `LiveVue.Encoder` protocol for a custom struct (`User`) to enable passing complex data structures as props between LiveView and Vue. This involves deriving `LiveVue.Encoder` and defining the struct's fields. It allows for serialization and deserialization of custom data types. ```elixir # For any custom structs you want to pass as props defmodule User do @derive LiveVue.Encoder defstruct [:name, :email, :age] end ``` -------------------------------- ### Configure Fly.io Database Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Guides the user through configuring a database for their Fly.io deployment. This involves selecting a database type (e.g., Fly Postgres), naming it, and adjusting settings for cost-effectiveness. ```bash ? Do you want to tweak these settings before proceeding? (y/N) y ``` -------------------------------- ### Initialize Fly.io App Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Initializes a new application on Fly.io. This command is used to set up the necessary configuration files and deploy your application to the Fly.io platform. ```bash fly launch ``` -------------------------------- ### LiveVue Custom Component Resolution Logic (JavaScript) Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Provides an example of custom component resolution logic within the `resolve` function of `createLiveVue`. This allows for flexible mapping of component names to their respective Vue files, including lazy loading specific components by their unique identifiers. ```javascript resolve: name => { // Custom component mapping and lazy loading const componentMap = { 'MyCounter': () => import('./components/Counter.vue'), 'admin/Dashboard': () => import('./admin/Dashboard.vue') } return componentMap[name] } ``` -------------------------------- ### Render Vue Component in LiveView (Elixir) Source: https://github.com/valian/live_vue/blob/main/guides/getting_started.md This snippet demonstrates how to render a Vue component within a LiveView template using the `vue` component macro. It shows how to pass assigns like `@current_user` and `@socket` as props to the Vue component. Ensure LiveVue is properly set up in your project. ```elixir def render(assigns) do ~H""" <.vue user={@current_user} v-component="UserProfile" v-socket={@socket} /> """ end ``` -------------------------------- ### Open Fly.io App Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Opens the deployed application in the web browser after a successful deployment on Fly.io. This command is a convenient way to access your live application. ```bash fly apps open ``` -------------------------------- ### Project Installation using Igniter Installer Source: https://github.com/valian/live_vue/blob/main/README.md These bash commands demonstrate how to install LiveVue in a new or existing Phoenix project using the `igniter` installer. The commands cover both creating a new project with LiveVue pre-configured and adding LiveVue to an existing Phoenix 1.8+ project. ```bash mix archive.install hex igniter_new mix igniter.new my_app --with phx.new --install live_vue@1.0.0-rc.3 ``` ```bash mix igniter.install live_vue@1.0.0-rc.3 ``` -------------------------------- ### Test LiveVue.Encoder implementation Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Provides an example of how to test your `LiveVue.Encoder` implementation in IEx. This allows you to verify that your custom encoders are correctly serializing your structs before passing them to LiveVue components. ```elixir # Test your encoder implementation iex> user = %User{name: "John", email: "john@example.com"} iex> LiveVue.Encoder.encode(user) %{name: "John", email: "john@example.com"} ``` -------------------------------- ### Install Playwright Dependencies and Browsers Source: https://github.com/valian/live_vue/blob/main/test/e2e/README.md Installs necessary Playwright dependencies and browsers required for running end-to-end tests. This involves running npm scripts and Playwright's browser installation command. ```bash npm run e2e:install npx playwright install ``` ```bash cd test/e2e && npx playwright install ``` -------------------------------- ### LiveState Channel and Client Setup Source: https://github.com/valian/live_vue/blob/main/guides/comparison.md Defines a LiveState channel in Elixir for managing application state and demonstrates the client-side JavaScript setup to connect, listen for state changes, and dispatch events. ```elixir defmodule MyApp.TodoChannel do use LiveState.Channel, web_module: MyAppWeb def init(_channel, _payload, _socket) do {:ok, %{todos: []}} end def handle_event("add_todo", todo, %{todos: todos}) do {:noreply, %{todos: [todo | todos]}} end end ``` ```javascript // Client (any framework) import LiveState from 'phx-live-state' const liveState = new LiveState({ url: 'ws://localhost:4000/socket', topic: 'todos:lobby' }) liveState.addEventListener('state_change', (state) => { // Update UI with new state }) liveState.dispatchEvent('add_todo', { title: 'New todo' }) ``` -------------------------------- ### Build Server Bundle for Production SSR - Bash Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Builds the server bundle required for production Server-Side Rendering (SSR) using npm. This command should be executed as part of your deployment script. The output is typically `priv/static/server.mjs`. ```bash # In your deployment script cd assets && npm run build-server ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/valian/live_vue/blob/main/CLAUDE.md Provides examples of commit messages using the conventional commit format for feature additions and bug fixes. ```git feat: add comprehensive frontend testing suite - Add Vitest testing framework with jsdom environment - Create comprehensive test suite for jsonPatch.ts - Add separate GitHub Actions workflow for frontend testing ``` ```git fix: handle nil values in prop diffing - Correctly encode nil values in SSR mode - Add test cases for nil prop scenarios ``` -------------------------------- ### Setup Vue Component Hooks with LiveVue Source: https://context7.com/valian/live_vue/llms.txt This JavaScript snippet shows how to initialize LiveVue and register Vue components using the `getHooks` function. It outlines the necessary imports and the configuration for LiveSocket. Dependencies include `phoenix_socket`, `phoenix_live_view`, and `live_vue`. ```javascript import { Socket } from "phoenix" import { LiveSocket } from "phoenix_live_view" import { getHooks } from "live_vue" import * as Vue from "vue" // Import Vue components import Counter from "../vue/Counter.vue" import UserProfile from "../vue/UserProfile.vue" const hooks = getHooks({ Counter, UserProfile, }, { initializeApp: ({ createApp, component, props, slots, plugin, el }) => { const app = createApp(component, props) app.provide("slots", slots) app.use(plugin) app.mount(el) return app } }) let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") let liveSocket = new LiveSocket("/live", Socket, { hooks, params: { _csrf_token: csrfToken }, dom: { onBeforeElUpdated(from, to) { if (from._x_dataStack) { window.Alpine.clone(from, to) } } } }) liveSocket.connect() window.liveSocket = liveSocket ``` -------------------------------- ### Vue Form Handling with useLiveForm Source: https://github.com/valian/live_vue/blob/main/guides/client_api.md Demonstrates basic usage of the useLiveForm composable for creating reactive forms. It covers type-safe field access, automatic validation display, and managing dynamic arrays. This example assumes a Vue 3 setup with the script setup syntax. ```vue ``` -------------------------------- ### Generate Phoenix Release Dockerfile Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Generates a Dockerfile for a Phoenix release, which is a prerequisite for containerized deployments. This command sets up the basic structure for building and deploying a Phoenix application within a Docker container. ```bash mix phx.gen.release --docker ``` -------------------------------- ### Access LiveView Hook Instance in Vue ``` ```html ``` -------------------------------- ### Configure ViteJS SSR Module for Development Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Configures the LiveVue project to use ViteJS for Server-Side Rendering (SSR) during development. This setup utilizes Vite's `ssrLoadModule` for efficient compilation and hot module replacement. ```elixir # config/dev.exs config :live_vue, ssr_module: LiveVue.SSR.ViteJS, vite_host: "http://localhost:5173" ``` -------------------------------- ### Modify Dockerfile for Node.js Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Updates a generated Dockerfile to include Node.js installation in both the build and production stages. This is crucial for applications that rely on Node.js for asset compilation or server-side rendering (SSR). ```dockerfile # Build Stage FROM hexpm/elixir:1.14.4-erlang-25.3.2-debian-bullseye-20230227-slim AS builder # Set environment variables ...(about 15 lines omitted)... # Install build dependencies RUN apt-get update -y && apt-get install -y build-essential git curl \ && apt-get clean && rm -f /var/lib/apt/lists/*_* # Install Node.js for build stage RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && apt-get install -y nodejs # Copy application code COPY . . # Install npm dependencies RUN cd /app/assets && npm install ...(about 20 lines omitted)... # Production Stage FROM ${RUNNER_IMAGE} RUN apt-get update -y && \ apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates curl \ && apt-get clean && rm -f /var/lib/apt/lists/*_* # Install Node.js for production RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && apt-get install -y nodejs ...(remaining dockerfile content)... ``` -------------------------------- ### Animated Vue Counter Component with LiveView Source: https://github.com/valian/live_vue/blob/main/guides/getting_started.md An enhanced Vue.js component (`AnimatedCounter.vue`) that displays a count with smooth enter/leave transitions using Vue's `` component and Tailwind CSS for styling. It accepts a `count` prop and emits an 'inc' event similar to the basic counter. Dependencies include Vue.js, LiveView, and Tailwind CSS. Inputs are props from LiveView; outputs are 'inc' events. Client-side animations are handled entirely within Vue. ```html ``` ```elixir defmodule MyAppWeb.CounterLive do use MyAppWeb, :live_view def render(assigns) do ~H"""

Animated Counter

<.vue count={@count} v-component="AnimatedCounter" v-socket={@socket} />
""" end # ... (mount and handle_event functions would be similar to the basic counter) end ``` -------------------------------- ### Setting Up NodeJS Supervisor for Production SSR Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Provides guidance on configuring the NodeJS supervisor within the Elixir application's children list for production SSR environments. It also includes a check for the existence of the server bundle file. ```elixir # application.ex children = [ {NodeJS.Supervisor, [path: LiveVue.SSR.NodeJS.server_path(), pool_size: 4]}, # ... other children ] ``` ```bash ls priv/static/server.mjs # Should exist after build ``` -------------------------------- ### Configure NodeJS Supervisor for Production SSR - Elixir Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Configures the NodeJS supervisor for production Server-Side Rendering (SSR) in an Elixir application. It specifies the path to the Node.js server and the pool size for handling concurrent requests. Ensure Node.js 19+ is installed. ```elixir children = [ {NodeJS.Supervisor, [path: LiveVue.SSR.NodeJS.server_path(), pool_size: 4]}, # ... other children ] ``` -------------------------------- ### Basic Component Test with LiveVue in Elixir Source: https://github.com/valian/live_vue/blob/main/guides/testing.md A basic test for a Vue component using LiveVue.Test. It renders a component, retrieves its Vue configuration using `Test.get_vue/2`, and asserts the component name and initial props. ```elixir defmodule MyAppWeb.CounterTest do use MyAppWeb.ConnCase alias LiveVue.Test test "renders counter component with initial props", %{conn: conn} do {:ok, view, _html} = live(conn, "/counter") vue = Test.get_vue(view) assert vue.component == "Counter" assert vue.props == %{"count" => 0} end end ``` -------------------------------- ### Vue Counter Component with LiveView Integration Source: https://github.com/valian/live_vue/blob/main/guides/getting_started.md A Vue.js component (`Counter.vue`) that displays a count received as a prop from LiveView and allows user interaction to increment the count. It uses local state for a slider to control the increment amount and emits an 'inc' event to LiveView. Dependencies include Vue.js and LiveView. Inputs are props from LiveView; outputs are 'inc' events. No server-side rendering is involved for the Vue component itself. ```html ``` ```elixir defmodule MyAppWeb.CounterLive do use MyAppWeb, :live_view def render(assigns) do ~H""" <.vue count={@count} v-component="Counter" v-socket={@socket} /> """ end def mount(_params, _session, socket) do {:ok, assign(socket, count: 0)} end def handle_event("inc", %{"diff" => value}, socket) do {:noreply, update(socket, :count, &(&1 + value))} end end ``` ```elixir scope "/" do pipe_through :browser live "/counter", CounterLive end ``` -------------------------------- ### Configure Global SSR Settings Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Defines global settings for Server-Side Rendering (SSR) in the LiveVue project, including enabling SSR by default and specifying the path to the server bundle. ```elixir # Global SSR settings config :live_vue, ssr: true, # Enable SSR by default ssr_filepath: "./static/server.mjs" # Server bundle path ``` -------------------------------- ### Add Heroku Node.js Buildpack Source: https://github.com/valian/live_vue/blob/main/guides/deployment.md Adds the Node.js buildpack to a Heroku application. This is a necessary step for deploying applications that require Node.js on the Heroku platform, ensuring Node.js is available during the build process. ```bash heroku buildpacks:add --index 1 heroku/nodejs ``` -------------------------------- ### Logging LiveView Events for Network Debugging Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Demonstrates how to log incoming LiveView events and their parameters within the `handle_event` function in Elixir. This helps in debugging network communication and verifying that events are received correctly. ```elixir def handle_event(event, params, socket) do IO.inspect({event, params}, label: "LiveView Event") # ... handle event end ``` -------------------------------- ### Implementing Lazy Loading for Vue Components Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Demonstrates how to implement lazy loading for Vue components to improve initial page load performance. By dynamically importing components, the application only loads what is immediately needed. ```javascript // assets/vue/index.js const components = { Counter: () => import('./Counter.vue'), Modal: () => import('./Modal.vue') } ``` -------------------------------- ### Configure NodeJS SSR Module for Production Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Sets up the LiveVue project to use NodeJS for Server-Side Rendering (SSR) in production environments. This configuration leverages `elixir-nodejs` with a pre-built server bundle for optimal performance. ```elixir # config/prod.exs config :live_vue, ssr_module: LiveVue.SSR.NodeJS, ssr: true ``` -------------------------------- ### LiveVue Component Integration with LiveView Source: https://github.com/valian/live_vue/blob/main/guides/comparison.md Shows how to embed a Vue.js component within a LiveView template using the `<.vue>` helper and demonstrates the corresponding Vue component template and script setup. ```elixir <.vue v-component="Counter" v-socket={@socket} count={@count} v-on:increment={JS.push("inc")} /> ``` ```html ``` -------------------------------- ### LiveVue Development Configuration (Elixir) Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Sets up LiveVue for a development environment in `config/dev.exs`. It specifically configures the SSR module to use ViteJS and sets the Vite development server host. This configuration is optimized for rapid development cycles. ```elixir # config/dev.exs config :live_vue, ssr_module: LiveVue.SSR.ViteJS, vite_host: "http://localhost:5173", ssr: true ``` -------------------------------- ### Elixir Server-Side Form Setup for Live View Source: https://github.com/valian/live_vue/blob/main/usage-rules.md Demonstrates how to set up server-side forms in Elixir using LiveView. It includes mounting the form with a changeset, handling validation events, and processing submit events, integrating with a database via Repo. ```elixir defmodule MyApp.Live.FormTest do use LiveVue, :live_view def render(assigns) do ~H""" <.vue form={@form} v-component="UserForm" v-socket={@socket} /> """ end def mount(params, socket) do changeset = MyApp.User.changeset(%MyApp.User{}, %{}) socket = assign(socket, form: to_form(changeset, as: :user)) {:ok, socket} end def handle_event("validate", params, socket) do changeset = MyApp.User.changeset(%MyApp.User{}, params) {:noreply, assign(socket, form: to_form(changeset, as: :user))} end def handle_event("submit", params, socket) do changeset = MyApp.User.changeset(%MyApp.User{}, params) case Repo.insert(changeset) do {:ok, _user} -> {:noreply, socket} {:error, changeset} -> {:noreply, assign(socket, form: to_form(changeset, as: :user))} end end end ``` -------------------------------- ### Build and Watch Assets with Mix Source: https://github.com/valian/live_vue/blob/main/README.md Commands to build static assets for LiveVue or start a watcher for continuous recompilation during development. These commands are typically run using Elixir's Mix build tool. ```bash mix assets.build ``` ```bash mix assets.watch ``` -------------------------------- ### Testing Multiple Vue Components by Name or ID in Elixir Source: https://github.com/valian/live_vue/blob/main/guides/testing.md Demonstrates how to test specific Vue components when multiple are present on a view. It shows how to use `Test.get_vue/2` with `name` or `id` options to target the desired component for assertions. ```elixir # Find by component name vue = Test.get_vue(view, name: "UserProfile") # Find by ID vue = Test.get_vue(view, id: "profile-1") ``` ```elixir def render(assigns) do ~H"""
<.vue id="profile-1" name="John" v-component="UserProfile" /> <.vue id="card-1" name="Jane" v-component="UserCard" />
""" end test "finds specific component" do html = render_component(&my_component/1) # Get UserCard component vue = Test.get_vue(html, name: "UserCard") assert vue.props == %{"name" => "Jane"} # Get by ID vue = Test.get_vue(html, id: "profile-1") assert vue.component == "UserProfile" end ``` -------------------------------- ### Configure Custom Vue Root Directories in LiveView Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Shows how to configure custom paths for Vue component discovery within a LiveView module. This allows for organizing Vue components in different directories and accessing them efficiently. ```elixir # lib/my_app_web.ex defmodule MyAppWeb do def html_helpers do quote do use LiveVue.Components, vue_root: [ "./assets/vue", "./lib/my_app_web", "./lib/my_app_web/components" ] end end end ``` -------------------------------- ### Managing TypeScript and Vite Build Dependencies Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Addresses build failures by ensuring compatibility between TypeScript and Vite. It suggests specific versions for `typescript` and `vue-tsc` to resolve compilation errors and provides a command to clear the Vite cache for build issues. ```bash # Check TypeScript version compatibility npm install typescript@5.5.4 vue-tsc@2.10.0 ``` ```bash # Clear Vite cache rm -rf node_modules/.vite npm run build ``` -------------------------------- ### Debugging Vue Component Prop Changes with Watchers Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Provides an example of using Vue's `watch` function to log changes in component props. This is a useful technique for understanding how data flows into a component and tracking unexpected modifications. ```html ``` -------------------------------- ### Error Handling: Component Not Found in LiveVue Source: https://github.com/valian/live_vue/blob/main/guides/component_reference.md Illustrates how LiveVue handles a missing component. If the specified `v-component` does not exist, an error will be logged to the browser's console. This example shows a basic setup where `Counter.vue` is expected but might be missing. ```elixir <.vue v-component="Counter" v-socket={@socket} /> ``` -------------------------------- ### LiveVue Component Eager Loading (JavaScript) Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Demonstrates eager loading of all Vue components within the application using Vite's `import.meta.glob`. This approach bundles all components into the main application chunk, suitable for smaller applications or when initial load performance is critical. ```javascript const components = { ...import.meta.glob("./**/*.vue", { eager: true }), } ``` -------------------------------- ### Ensure LiveVue prop names match client-side Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md This example demonstrates how server-side (Elixir) and client-side (Vue.js) prop names must match exactly for LiveVue components to receive updates. Mismatched prop names can cause components to not update even when data changes. ```elixir # Server side <.vue user_name={@user.name} v-component="Profile" v-socket={@socket} /> ``` ```html ``` -------------------------------- ### Configure Shared Props for LiveVue Components - Elixir Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Configures shared props that are automatically passed to all Vue components rendered within LiveView contexts. This example shows how to pass flash messages, current user data, and locale settings. Supports direct, renamed, and nested mapping. ```elixir config :live_vue, shared_props: [ :flash, {:current_user, :user}, :locale ] ``` ```elixir config :live_vue, shared_props: [:flash, :current_user] ``` ```elixir config :live_vue, shared_props: [{:current_user, :user}, {:user_preferences, :prefs}] ``` ```elixir config :live_vue, shared_props: [ {[:scope, :user], :user}, {[:streams, :items], :items} ] ``` -------------------------------- ### Analyzing and Optimizing Bundle Size with Vite Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Offers a command to analyze the application's bundle size using Vite's build analyze feature. This helps identify large dependencies or code chunks that can be optimized to improve loading performance. ```bash # Analyze bundle npm run build -- --analyze ``` -------------------------------- ### Handling Dates and Times in LiveVue Components (Elixir to Vue) Source: https://github.com/valian/live_vue/blob/main/guides/component_reference.md Shows how to pass Elixir `Date` and `DateTime` objects as props to a Vue component. LiveVue automatically serializes these into ISO 8601 formatted strings. The example includes both the Elixir code for passing the props and the Vue.js script setup for receiving and parsing them. ```elixir # Dates are serialized as ISO strings <.vue v-component="Calendar" v-socket={@socket} current_date={Date.utc_today()} created_at={DateTime.utc_now()} /> ``` ```html ``` -------------------------------- ### LiveVue Component Lazy Loading Options (JavaScript) Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Illustrates lazy loading strategies for Vue components using JavaScript `import` and Vite's glob import. This improves initial load times by only loading components when they are needed. It shows both explicit component imports and dynamic glob imports for organizing components. ```javascript const components = { Counter: () => import("./Counter.vue"), Modal: () => import("./Modal.vue") } // Or using Vite's glob import // useful if we colocate Vue components with LiveView components and want to put each of them into a separate chunk // all shared components imported by top-level components will be included as well. const components = import.meta.glob( "../../lib/**/*.vue", { eager: false, import: 'default' } ) ``` -------------------------------- ### LiveView Server Setup with Streams (Elixir) Source: https://github.com/valian/live_vue/blob/main/guides/basic_usage.md Configures a LiveView module to utilize streams for managing and updating collections of data. It initializes the stream with sample items and defines event handlers for adding and removing items, leveraging `stream/3`, `stream_insert/3`, and `stream_delete_by_dom_id/4` for efficient data synchronization between server and client. ```elixir defmodule MyAppWeb.ItemsLive do use MyAppWeb, :live_view def render(assigns) do ~H""" <.vue items={@streams.items} v-component="ItemList" v-socket={@socket} /> """ end def mount(_params, _session, socket) do # Initialize with sample items items = [ %{id: 1, name: "Item 1"}, %{id: 2, name: "Item 2"}, %{id: 3, name: "Item 3"} ] {:ok, stream(socket, :items, items)} end def handle_event("add_item", %{"name" => name}, socket) do new_item = %{ id: Enum.random(1..1000), name: name } {:noreply, stream_insert(socket, :items, new_item)} end def handle_event("remove_item", %{"id" => id}, socket) do {:noreply, stream_delete_by_dom_id(socket, :items, "item-" <> id)} end end ``` -------------------------------- ### LiveVue Hook Initialization (JavaScript) Source: https://github.com/valian/live_vue/blob/main/guides/faq.md This JavaScript code outlines the initialization process for a LiveVue hook. The hook mounts on element creation, sets up event handlers, injects the hook for `useLiveVue`, and mounts the Vue component, enabling client-side interactivity. ```javascript // LiveVue hook initialization logic // Mounts on element creation // Sets up event handlers // Injects the hook for useLiveVue // Mounts the Vue component ``` -------------------------------- ### Vue Component Shortcut Syntax Source: https://github.com/valian/live_vue/blob/main/guides/basic_usage.md Illustrates the shortcut syntax for rendering Vue components, where the component name can be directly used as a function name, simplifying the HEEX template. It also shows how to reference deeply nested components. ```elixir <.Counter count={@count} v-socket={@socket} /> <.vue v-component="helpers/nested/Modal" /> ``` -------------------------------- ### Access Deeply Nested Arrays in Valian Live Vue Forms (TypeScript) Source: https://github.com/valian/live_vue/blob/main/guides/forms.md Demonstrates how to access deeply nested array structures within Valian Live Vue forms using TypeScript. This example covers arrays within arrays within objects, showing how to chain `fieldArray` and `field` calls to reach specific nested data. It includes examples using both direct bracket notation and fluent interface chaining for accessing nested fields like paragraphs or comments within sections of a blog post. ```typescript type BlogPost = { title: string sections: Array<{ heading: string paragraphs: string[] comments: Array<{ author: string text: string replies: Array<{ author: string text: string }> }> }> } const form = useLiveForm(/* ... */) // Access deeply nested arrays const sectionsArray = form.fieldArray('sections') const firstSectionParagraphs = sectionsArray.field('[0].paragraphs') // FormFieldArray const firstSectionComments = sectionsArray.field('[0].comments') // FormFieldArray // Using fluent interface const firstSection = sectionsArray.field(0) // FormField
const firstSectionParagraphsAlt = firstSection.fieldArray('paragraphs') // FormFieldArray // Access replies of first comment in first section const firstCommentReplies = sectionsArray.fieldArray('[0].comments').field('[0].replies') // FormFieldArray ``` -------------------------------- ### Watch and Build Assets Source: https://github.com/valian/live_vue/blob/main/CLAUDE.md Commands for managing frontend assets. `mix assets.watch` automatically rebuilds assets on changes during development. `mix assets.build` performs a one-time build. ```bash mix assets.watch mix assets.build ``` -------------------------------- ### LiveView Component Discovery in Build System Source: https://github.com/valian/live_vue/blob/main/CLAUDE.md Build system configuration that uses `import.meta.glob` to dynamically discover Vue components located in the `test/e2e/vue/` directory. This enables eager loading of components for use in LiveView. ```javascript import.meta.glob("../vue/**/*.vue", { eager: true }) ``` -------------------------------- ### Debug: Inspect LiveVue assigns before and after update Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Provides Elixir code for inspecting the `socket.assigns` before and after an event handler modifies them. This is useful for verifying that assigns are being updated correctly, which is essential for component reactivity. ```elixir # Add debug logging def handle_event("update", _params, socket) do IO.inspect(socket.assigns, label: "Before update") socket = assign(socket, :count, socket.assigns.count + 1) IO.inspect(socket.assigns, label: "After update") {:noreply, socket} end ``` -------------------------------- ### Fix: Add `v-socket` attribute to LiveVue component Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Ensures the LiveVue component is correctly associated with its socket. This is crucial for communication between the server and client. Missing this attribute can lead to components not rendering. ```elixir # ❌ Missing v-socket <.vue v-component="Counter" count={@count} /> # ✅ Correct <.vue v-component="Counter" count={@count} v-socket={@socket} /> ``` -------------------------------- ### Enable Debug Logging for LiveVue - Elixir Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Enables debug logging for the application and demonstrates how to log Vue component props within an Elixir component. For frontend debugging, VueDevTools is recommended. ```elixir config :logger, level: :debug # In your component require Logger Logger.debug("Vue component props: #{inspect(props)}") ``` -------------------------------- ### LiveView: Setup Contact Form Handling Source: https://github.com/valian/live_vue/blob/main/guides/forms.md This LiveView module demonstrates basic form handling for a Contact form. It sets up the initial form state using `to_form` and handles 'validate' and 'submit' events, showing how to process form data and update the form state based on validation results or successful submission. ```elixir defmodule MyAppWeb.ContactFormLive do use MyAppWeb, :live_view def render(assigns) do ~H""" <.vue form={@form} v-component="ContactForm" v-socket={@socket} /> """ end def mount(_params, _session, socket) do changeset = Contact.changeset(%Contact{}, %{}) {:ok, assign(socket, form: to_form(changeset, as: :contact))} end def handle_event("validate", %{"contact" => params}, socket) do changeset = Contact.changeset(%Contact{}, params) {:noreply, assign(socket, form: to_form(changeset, as: :contact))} end def handle_event("submit", %{"contact" => params}, socket) do changeset = Contact.changeset(%Contact{}, params) case Repo.insert(changeset) do {:ok, contact} -> {:noreply, put_flash(socket, :info, "Contact created successfully!")} {:error, changeset} -> {:noreply, assign(socket, form: to_form(changeset, as: :contact))} end end end ``` -------------------------------- ### Configure LiveVue Components Shortcut (Elixir) Source: https://github.com/valian/live_vue/blob/main/guides/component_reference.md Setup for enabling shortcut syntax for Vue components in LiveView by configuring `LiveVue.Components` in your `web.ex` file. This allows for cleaner component usage. ```elixir # In lib/my_app_web.ex defp html_helpers do quote do use LiveVue.Components, vue_root: [ "./assets/vue", "./lib/my_app_web" ] end end ``` -------------------------------- ### Debug: Log available Vue components in LiveVue Source: https://github.com/valian/live_vue/blob/main/guides/troubleshooting.md Helps diagnose 'Component not found' errors by logging all components that LiveVue is aware of. This is useful for verifying that your component resolution in `assets/vue/index.js` is working correctly. ```javascript // Check your component resolution in assets/vue/index.js const components = { ...import.meta.glob("./**/*.vue", { eager: true }), } // Debug: log available components console.log("Available components:", Object.keys(components)) ``` -------------------------------- ### LiveVue Application Configuration Options (Elixir) Source: https://github.com/valian/live_vue/blob/main/guides/configuration.md Defines the core configuration settings for LiveVue in `config/config.exs`. It includes options for Server-Side Rendering (SSR) module and behavior, Vite development server URL, SSR file path, props diffing, and shared props. These settings control how LiveVue integrates with your Elixir application and Vue components. ```elixir import Config config :live_vue, # SSR module selection # For development: LiveVue.SSR.ViteJS # For production: LiveVue.SSR.NodeJS ssr_module: nil, # Default SSR behavior # Can be overridden per-component with v-ssr={true|false} ssr: true, # Vite development server URL # Typically http://localhost:5173 in development vite_host: nil, # SSR server bundle path (relative to priv directory) # Created by Vite "build-server" command ssr_filepath: "./static/server.mjs", # Testing configuration # When false, we will always update full props and not send diffs # Useful for testing scenarios where you need complete props state enable_props_diff: true, # Shared props configuration # Props that are automatically added to all Vue components shared_props: [] ``` -------------------------------- ### Run End-to-End Tests (Playwright) Source: https://github.com/valian/live_vue/blob/main/CLAUDE.md Executes Playwright end-to-end tests located in `test/e2e/`. These tests interact with a live Phoenix server and Vue components. Includes commands for installation, headed execution, and debugging. ```bash npm run e2e:test # Additional E2E commands: # npm run e2e:install - Install E2E test dependencies # npm run e2e:test:headed - Run tests with browser UI visible # npm run e2e:test:debug - Run tests in debug mode with Playwright inspector # npm run e2e:server - Start E2E test server manually (runs on port 4004) ``` -------------------------------- ### Render Vue Component with HEEX Source: https://github.com/valian/live_vue/blob/main/guides/basic_usage.md Demonstrates the basic syntax for rendering a Vue component from a HEEX template using the '<.vue>' function. It shows required attributes like 'v-component' and 'v-socket', and optional attributes for event handling and props. ```elixir <.vue count={@count} v-component="Counter" v-socket={@socket} v-on:inc={JS.push("inc")} /> ``` -------------------------------- ### File Uploads with useLiveUpload Hook (Vue) Source: https://github.com/valian/live_vue/blob/main/usage-rules.md Illustrates the usage of the useLiveUpload hook for handling file uploads in Vue components. It shows how to initialize the hook with upload configuration, manage file entries, track progress, and interact with the file picker. The provided template example includes drag-and-drop functionality and displays upload status. ```vue ``` ```vue ```