Differences from React
Where @chelone/vue departs from the React pages, so you know which code does not carry over.
Most pages in these docs show React code. @chelone/vue has the same
components, controllers and hooks, so a page still describes the behaviour. This
page lists where the Vue code is written differently. Setup is on the
Vue setup page.
The general mapping:
- Props are kebab-case in templates:
:data-provider,:query-client. - A React callback prop such as
onConfirmis an emitted event:@confirm. - A
ReactNodeprop is a slot:#layout,#dashboard,#error. - A component prop takes the component itself, not a render function:
:list="PostList". - A composable returns
Refs where the React hook returns plain values.
The admin
| React | Vue | React page |
|---|---|---|
<Admin router={...}> swaps the router adapter. | There is no router prop and no router swap. <Admin> uses the vue-router the app installs. | Swapping the router |
The children can be a function that receives permissions. | The default slot takes no arguments. | Auth, basename and permissions |
<Admin.Title> and the title prop set the admin title. | There is no <Admin.Title> and no title slot. | Admin |
With no layout given, <Admin> renders the routes with no layout. | A default layout renders when no #layout slot is given. | The layout slot |
The Zod registry prop is resources. | The Zod registry prop is registry. resources is an array of view definitions, the way to register a resource without a <Resource> child. | The resources prop |
<CustomRoutes> children add routes. | customRoutes is an array prop, read once. | Custom Routes |
The error fallback receives { error, errorInfo, resetErrorBoundary }. | The #error slot receives { error, info, reset }. info is Vue's description of where the error was thrown. | Error |
ResourceDefinition takes options, so resources group in the menu and carry a label override. | ResourceDefinition has no options: the menu is one flat group, and a resource label comes from the translation key or the humanized name. | Resource |
The full prop list for <Admin> and <Resource> is on the
Vue setup page.
Forms and hooks
| React | Vue | React page |
|---|---|---|
<TabbedForm.Tab> and <WizardForm.Step> are statics on the form. | TabbedFormTab and WizardFormStep are separate components, imported from @chelone/vue. | Tabbed Form, Wizard Form |
useStoreItem(key, default) returns [value, setter] and follows a changing key. | useStoreItem returns [Ref, setter]. The key and default are read once, in setup. | None |
A field or input label is a ReactNode. | label is a string, or false to hide it. An input takes no label markup. <FieldLabelText> renders its default slot as the label, for a label you build yourself. | Text Input |
<FilterForm> selects the displayed filters with alwaysOn and a remove control per input. | <FilterForm> shows the inputs slotted into it. There is no alwaysOn and no displayed-filter selection. | Filter Form |
Components
| React | Vue | React page |
|---|---|---|
<Confirm> takes onConfirm and onClose. | <Confirm> emits confirm and close. | Confirm |
<BooleanField> takes TrueIcon and FalseIcon. | <BooleanField> has no TrueIcon or FalseIcon props. It draws a built-in check or cross, styled through class. | Boolean Field |
<FileInput> and <ImageInput> use react-dropzone. | They use native drag and drop. The value shape is the same: { rawFile, src, title } for a dropped file. | File Input, Image Input |
<Notification> renders through sonner. | <Notification> is a dependency-free toaster, a stack at the bottom centre with its own close button. | Notification |
<ThemeModeToggle> opens a dropdown of modes. | <ThemeModeToggle> is one button. Each click cycles light, dark, system. | Theme Mode Toggle |
<IconButtonWithTooltip> shows a styled tooltip. | <IconButtonWithTooltip> shows the native title, because the Vue ui slice has no Tooltip. Its label is also the aria-label; a #label slot stands in for a non-string label. | Icon Button With Tooltip |
<SimpleList> takes function props such as primaryText. | <SimpleList> takes scoped slots such as #primary-text, each given { record, id }. | Simple List |
<SimpleFormIterator> is a child of <ArrayInput>. | There is no <SimpleFormIterator>. <ArrayInput> takes disableAdd, disableRemove, inline and the rest as props, with the #add-button, #remove-button and #reorder-buttons slots. | Simple Form Iterator |
<TabbedShowLayout>, <TranslatableInputs> and <TranslatableFields> draw their tabs with ui/tabs. | They draw native buttons with role="tab". The tab child of <TabbedShowLayout> is TabbedShowLayoutTab, imported from @chelone/vue. | Tabbed Show Layout, Translatable Inputs, Translatable Fields |
<TranslatableInputs> and <TranslatableFields> take a selector element. | They take a #selector slot. | Translatable Inputs, Translatable Fields |
<RefreshIconButton> shows a styled tooltip. | <RefreshIconButton> shows the native title, and its label is also the aria-label. | Refresh Icon Button |
<BulkEditDrawer> opens a Sheet. | <BulkEditDrawer> opens an inline panel that is not teleported. | Bulk Edit Drawer |
<FilterLiveSearch> builds on FilterLiveForm. | <FilterLiveSearch> builds on <FilterForm>, because Vue has no FilterLiveForm. | Filter Live Search |
<ColumnsButton> opens a Popover. | <ColumnsButton> shows its panel inside a DropdownMenu. The panel holds plain rows, so it stays open while you switch several columns. | Columns Button |
<TreeList> takes the onSelect, loading and empty props. | <TreeList> emits select and takes the #loading and #empty slots. With no select listener a row navigates, as React does with no onSelect. | Tree List |
<StatusTransitionButton> takes an onTransition prop. <DualApprovalButton> takes only props. | <StatusTransitionButton> emits a transition event with the same (from, to, record) arguments. <DualApprovalButton> takes the same props. | Status Transition Button, Dual Approval Button |
<CommandMenu> composes cmdk's Command with a teleported dialog. | <CommandMenu> composes the native ui/command family with an inline dialog that is not teleported. | Command Menu |
Theme storage differs too: the Vue <ThemeProvider> always uses localStorage
and useTheme() returns Refs. The note under
Themes has the details.
Add-ons
The Monaco components are an add-on, imported from @chelone/vue/monaco or
installed from the registry as @chelone/monaco. The Markdown components are
another, imported from @chelone/vue/mdx-editor or installed as
@chelone/mdx-editor.
| React | Vue | React page |
|---|---|---|
<MonacoJsonInput> and <MonacoJsonField> use @monaco-editor/react, and take className. The input also takes editorClassName. | They use @guolao/vue-monaco-editor, and take class. The input also takes editor-class. <MonacoJsonInput> has no id, resource, isRequired, format, parse or alwaysOn prop and emits no events. | Monaco Json Input, Monaco Json Field |
<MdxInput> and <MdxField> use @mdxeditor/editor and the mdxeditor-dark class. <MdxInput> has a fixed toolbar and takes mdxProps, whose plugins replace the defaults. <MdxField> has no toolbar and takes plugins and the other editor props directly. | They wrap Milkdown's Crepe editor, because MDXEditor is React only. The input's toolbar floats over a selection, crepeConfig replaces mdxProps and plugins on both components, and a theme file replaces the dark class. They take class, and <MdxInput> has no id, resource, isRequired, format, parse or alwaysOn prop. | Mdx Input, Mdx Field |
What this page leaves out
The list is the differences you write differently. Port details with no API effect, such as how a dropdown menu positions itself, are not listed.