New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@flow-render/vue

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@flow-render/vue

Render Vue components in async flows — make your UI awaitable

Source
npmnpm
Version
0.2.0
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

@flow-render/vue

English | 中文

Render Vue components in asynchronous flows — a Promise-based UI rendering approach that lets you naturally await user interactions, just like calling async functions.

Installation

npm i @flow-render/vue

Quick Start

Mount the Viewport

Place a <Viewport/> at the root of your application. All dynamically rendered components will appear here.

<!-- App.vue -->

<script setup lang="ts">
  import { Viewport } from '@flow-render/vue'
</script>

<template>
  <YourApp/>
  <Viewport/> <!-- Dynamic components are rendered here -->
</template>

Define Components

Flow Render supports two ways to write components; you can choose based on your scenario.

Components directly declare and use resolve/reject callbacks, similar to the new Promise((resolve, reject) => ...) executor style.

<!-- ConfirmDialog.vue -->

<script setup lang="ts">
  import { type PromiseResolvers } from '@flow-render/vue'

  interface Props extends PromiseResolvers<boolean> {
    title: string
  }

  let props = defineProps<Props>()
</script>

<template>
  <dialog open>
    <div>{{title}}</div>
    <div>
      <button @click="props.resolve(true)">Yes</button>
      <button @click="props.resolve(false)">No</button>
      <button @click="props.reject(new Error('Cancel'))">Cancel</button>
    </div>
  </dialog>
</template>

Callbacks are automatically injected when rendering:

import { render } from '@flow-render/vue'

const result = await render(ConfirmDialog, {
  title: 'Are you sure?'
})

Adapter Mode (Flexible and Powerful)

Adapter mode allows you to dynamically associate props of any component with a Promise. You simply provide a function that receives resolve and reject and returns the component's props. This approach not only works with existing components but also enables more complex logic, such as determining props based on external data, conditional rendering, dynamic bindings, etc.

<!-- ConfirmDialog.vue -->

<script setup lang="ts">
  interface Props {
    title: string
    onYes: () => void
    onNo: () => void
    onCancel: () => void
  }

  const props = defineProps<Props>()
</script>

<template>
  <dialog open>
    <div>{{props.title}}</div>
    <div>
      <button @click="props.onYes">Yes</button>
      <button @click="props.onNo">No</button>
      <button @click="props.onCancel">Cancel</button>
    </div>
  </dialog>
</template>

When rendering with adapter mode, you establish the connection between the Promise and component callbacks via an adapter function:

import { render } from '@flow-render/vue'

const result = await render(ConfirmDialog, (resolve, reject) => {
  return {
    title: 'Are you sure?',
    onYes: () => resolve(true),
    onNo: () => resolve(false),
    onCancel: () => reject(),
  }
})

children prop

Vue has a special children prop that is automatically mapped to the slots. When your component needs to receive children, exclude the children prop from Props, use <slot/> in the template.

<!-- ConfirmDialog.vue -->

<script setup lang="ts">
  import { type PromiseResolvers } from '@flow-render/vue'

  interface Props extends PromiseResolvers<boolean> {
    title: string
  }

  // Exclude 'children' from defineProps
  const props = defineProps<Props>()
</script>

<template>
  <dialog open>
    <div>{{ props.title }}</div>
    <!-- Render children via default slot -->
    <slot/>
    <button @click="props.resolve(true)">Yes</button>
  </dialog>
</template>

Pass children when rendering:

import { render } from '@flow-render/vue'

const result = await render(ConfirmDialog, {
  title: 'Confirm',
  children: 'Are you sure you want to continue?'
})

More

Full documentation

Keywords

vue

FAQs

Package last updated on 14 Mar 2026

Related posts