在 React 等项目中使用

大多数前端框架/库都能无缝使用自定义元素,比如分配 Attribute/Property,注册事件, 但是直接使用自定义元素没有类型提示,所以 DuoyunUI 进行了重导出,完美适配了 React/Vue/Svelte。

React

NOTE

React 19 才支持自定义元素,请确保安装 React 19。

跟使用其他 React 组件库一样使用 DuoyunUI:

import { useRef, useState } from 'react'; import Layout from '../components/layout'; import type { DyColorPickerMethods } from 'duoyun-ui/react/DyColorPicker'; import DyActionText, { DuoyunActionTextElement } from 'duoyun-ui/react/DyActionText' import DyActiveLink, { DuoyunActiveLinkElement } from 'duoyun-ui/react/DyActiveLink' import DyAlert, { DuoyunAlertElement } from 'duoyun-ui/react/DyAlert' import DyAreaChart, { DuoyunAreaChartElement } from 'duoyun-ui/react/DyAreaChart' import DyAvatar, { DuoyunAvatarElement } from 'duoyun-ui/react/DyAvatar' import DyAvatarGroup, { DuoyunAvatarGroupElement } from 'duoyun-ui/react/DyAvatarGroup' import DyBanner, { DuoyunBannerElement } from 'duoyun-ui/react/DyBanner' import DyBarChart, { DuoyunBarChartElement } from 'duoyun-ui/react/DyBarChart' import DyBreadcrumbs, { DuoyunBreadcrumbsElement } from 'duoyun-ui/react/DyBreadcrumbs' import DyButton, { DuoyunButtonElement } from 'duoyun-ui/react/DyButton' import DyCalendar, { DuoyunCalendarElement } from 'duoyun-ui/react/DyCalendar' import DyCard, { DuoyunCardElement } from 'duoyun-ui/react/DyCard' import DyCarousel, { DuoyunCarouselElement } from 'duoyun-ui/react/DyCarousel' import DyCascader, { DuoyunCascaderElement } from 'duoyun-ui/react/DyCascader' import DyCascaderPicker, { DuoyunCascaderPickerElement } from 'duoyun-ui/react/DyCascaderPicker' import DyChartTooltip, { DuoyunChartTooltipElement } from 'duoyun-ui/react/DyChartTooltip' import DyChartZoom, { DuoyunChartZoomElement } from 'duoyun-ui/react/DyChartZoom' import DyCheckbox, { DuoyunCheckboxElement } from 'duoyun-ui/react/DyCheckbox' import DyCheckboxGroup, { DuoyunCheckboxGroupElement } from 'duoyun-ui/react/DyCheckboxGroup' import DyCoachMark, { DuoyunCoachMarkElement } from 'duoyun-ui/react/DyCoachMark' import DyCodeBlock, { DuoyunCodeBlockElement } from 'duoyun-ui/react/DyCodeBlock' import DyCollapse, { DuoyunCollapseElement } from 'duoyun-ui/react/DyCollapse' import DyCollapsePanel, { DuoyunCollapsePanelElement } from 'duoyun-ui/react/DyCollapsePanel' import DyContextmenu, { DuoyunContextmenuElement } from 'duoyun-ui/react/DyContextmenu' import DyColorPanel, { DuoyunColorPanelElement } from 'duoyun-ui/react/DyColorPanel' import DyColorPicker, { DuoyunColorPickerElement } from 'duoyun-ui/react/DyColorPicker' import DyCompartment, { DuoyunCompartmentElement } from 'duoyun-ui/react/DyCompartment' import DyCopy, { DuoyunCopyElement } from 'duoyun-ui/react/DyCopy' import DyDatePanel, { DuoyunDatePanelElement } from 'duoyun-ui/react/DyDatePanel' import DyDatePicker, { DuoyunDatePickerElement } from 'duoyun-ui/react/DyDatePicker' import DyDateRangePanel, { DuoyunDateRangePanelElement } from 'duoyun-ui/react/DyDateRangePanel' import DyDateRangePicker, { DuoyunDateRangePickerElement } from 'duoyun-ui/react/DyDateRangePicker' import DyDivider, { DuoyunDividerElement } from 'duoyun-ui/react/DyDivider' import DyDonutChart, { DuoyunDonutChartElement } from 'duoyun-ui/react/DyDonutChart' import DyDrawer, { DuoyunDrawerElement } from 'duoyun-ui/react/DyDrawer' import DyDropArea, { DuoyunDropAreaElement } from 'duoyun-ui/react/DyDropArea' import DyEmpty, { DuoyunEmptyElement } from 'duoyun-ui/react/DyEmpty' import DyFilePicker, { DuoyunFilePickerElement } from 'duoyun-ui/react/DyFilePicker' import DyFlow, { DuoyunFlowElement } from 'duoyun-ui/react/DyFlow' import DyFlowCanvas, { DuoyunFlowCanvasElement } from 'duoyun-ui/react/DyFlowCanvas' import DyForm, { DuoyunFormElement } from 'duoyun-ui/react/DyForm' import DyFormItem, { DuoyunFormItemElement } from 'duoyun-ui/react/DyFormItem' import DyFormItemInlineGroup, { DuoyunFormItemInlineGroupElement } from 'duoyun-ui/react/DyFormItemInlineGroup' import DyGesture, { DuoyunGestureElement } from 'duoyun-ui/react/DyGesture' import DyHeading, { DuoyunHeadingElement } from 'duoyun-ui/react/DyHeading' import DyHelpText, { DuoyunHelpTextElement } from 'duoyun-ui/react/DyHelpText' import DyIcons, { DuoyunIconsElement } from 'duoyun-ui/react/DyIcons' import DyImagePreview, { DuoyunImagePreviewElement } from 'duoyun-ui/react/DyImagePreview' import DyInput, { DuoyunInputElement } from 'duoyun-ui/react/DyInput' import DyInputCapture, { DuoyunInputCaptureElement } from 'duoyun-ui/react/DyInputCapture' import DyInputGroup, { DuoyunInputGroupElement } from 'duoyun-ui/react/DyInputGroup' import DyKeyboardAccess, { DuoyunKeyboardAccessElement } from 'duoyun-ui/react/DyKeyboardAccess' import DyLegend, { DuoyunLegendElement } from 'duoyun-ui/react/DyLegend' import DyLightRoute, { DuoyunLightRouteElement } from 'duoyun-ui/react/DyLightRoute' import DyLineChart, { DuoyunLineChartElement } from 'duoyun-ui/react/DyLineChart' import DyLink, { DuoyunLinkElement } from 'duoyun-ui/react/DyLink' import DyList, { DuoyunListElement } from 'duoyun-ui/react/DyList' import DyListItem, { DuoyunListItemElement } from 'duoyun-ui/react/DyListItem' import DyLoading, { DuoyunLoadingElement } from 'duoyun-ui/react/DyLoading' import DyMap, { DuoyunMapElement } from 'duoyun-ui/react/DyMap' import DyMeter, { DuoyunMeterElement } from 'duoyun-ui/react/DyMeter' import DyModal, { DuoyunModalElement } from 'duoyun-ui/react/DyModal' import DyMore, { DuoyunMoreElement } from 'duoyun-ui/react/DyMore' import DyMoreSlot, { DuoyunMoreSlotElement } from 'duoyun-ui/react/DyMoreSlot' import DyOptions, { DuoyunOptionsElement } from 'duoyun-ui/react/DyOptions' import DyPageLoadbar, { DuoyunPageLoadbarElement } from 'duoyun-ui/react/DyPageLoadbar' import DyPagination, { DuoyunPaginationElement } from 'duoyun-ui/react/DyPagination' import DyParagraph, { DuoyunParagraphElement } from 'duoyun-ui/react/DyParagraph' import DyPicker, { DuoyunPickerElement } from 'duoyun-ui/react/DyPicker' import DyPlaceholder, { DuoyunPlaceholderElement } from 'duoyun-ui/react/DyPlaceholder' import DyPopover, { DuoyunPopoverElement } from 'duoyun-ui/react/DyPopover' import DyPopoverGhost, { DuoyunPopoverGhostElement } from 'duoyun-ui/react/DyPopoverGhost' import DyProgress, { DuoyunProgressElement } from 'duoyun-ui/react/DyProgress' import DyRadio, { DuoyunRadioElement } from 'duoyun-ui/react/DyRadio' import DyRadioGroup, { DuoyunRadioGroupElement } from 'duoyun-ui/react/DyRadioGroup' import DyRate, { DuoyunRateElement } from 'duoyun-ui/react/DyRate' import DyReflect, { DuoyunReflectElement } from 'duoyun-ui/react/DyReflect' import DyResult, { DuoyunResultElement } from 'duoyun-ui/react/DyResult' import DyRoute, { DuoyunRouteElement } from 'duoyun-ui/react/DyRoute' import DyScatterChart, { DuoyunScatterChartElement } from 'duoyun-ui/react/DyScatterChart' import DySelect, { DuoyunSelectElement } from 'duoyun-ui/react/DySelect' import DySelectionBox, { DuoyunSelectionBoxElement } from 'duoyun-ui/react/DySelectionBox' import DySelectionBoxMask, { DuoyunSelectionBoxMaskElement } from 'duoyun-ui/react/DySelectionBoxMask' import DyShortcutRecord, { DuoyunShortcutRecordElement } from 'duoyun-ui/react/DyShortcutRecord' import DySideNavigation, { DuoyunSideNavigationElement } from 'duoyun-ui/react/DySideNavigation' import DySlider, { DuoyunSliderElement } from 'duoyun-ui/react/DySlider' import DySpace, { DuoyunSpaceElement } from 'duoyun-ui/react/DySpace' import DyStatistic, { DuoyunStatisticElement } from 'duoyun-ui/react/DyStatistic' import DyStatusLight, { DuoyunStatusLightElement } from 'duoyun-ui/react/DyStatusLight' import DySwitch, { DuoyunSwitchElement } from 'duoyun-ui/react/DySwitch' import DyTable, { DuoyunTableElement } from 'duoyun-ui/react/DyTable' import DyTabPanel, { DuoyunTabPanelElement } from 'duoyun-ui/react/DyTabPanel' import DyTabs, { DuoyunTabsElement } from 'duoyun-ui/react/DyTabs' import DyTag, { DuoyunTagElement } from 'duoyun-ui/react/DyTag' import DyTextMask, { DuoyunTextMaskElement } from 'duoyun-ui/react/DyTextMask' import DyTimeline, { DuoyunTimelineElement } from 'duoyun-ui/react/DyTimeline' import DyTimePanel, { DuoyunTimePanelElement } from 'duoyun-ui/react/DyTimePanel' import DyTimePicker, { DuoyunTimePickerElement } from 'duoyun-ui/react/DyTimePicker' import DyTitle, { DuoyunTitleElement } from 'duoyun-ui/react/DyTitle' import DyToast, { DuoyunToastElement } from 'duoyun-ui/react/DyToast' import DyTooltip, { DuoyunTooltipElement } from 'duoyun-ui/react/DyTooltip' import DyTree, { DuoyunTreeElement } from 'duoyun-ui/react/DyTree' import DyUnsafe, { DuoyunUnsafeElement } from 'duoyun-ui/react/DyUnsafe' import DyUse, { DuoyunUseElement } from 'duoyun-ui/react/DyUse' import DyWait, { DuoyunWaitElement } from 'duoyun-ui/react/DyWait' if (typeof window !== 'undefined') { [DuoyunActionTextElement, DuoyunActiveLinkElement, DuoyunAlertElement, DuoyunAreaChartElement, DuoyunAvatarElement, DuoyunAvatarGroupElement, DuoyunBannerElement, DuoyunBarChartElement, DuoyunBreadcrumbsElement, DuoyunButtonElement, DuoyunCalendarElement, DuoyunCardElement, DuoyunCarouselElement, DuoyunCascaderElement, DuoyunCascaderPickerElement, DuoyunChartTooltipElement, DuoyunChartZoomElement, DuoyunCheckboxElement, DuoyunCheckboxGroupElement, DuoyunCoachMarkElement, DuoyunCodeBlockElement, DuoyunCollapseElement, DuoyunCollapsePanelElement, DuoyunContextmenuElement, DuoyunColorPanelElement, DuoyunColorPickerElement, DuoyunCompartmentElement, DuoyunCopyElement, DuoyunDatePanelElement, DuoyunDatePickerElement, DuoyunDateRangePanelElement, DuoyunDateRangePickerElement, DuoyunDividerElement, DuoyunDonutChartElement, DuoyunDrawerElement, DuoyunDropAreaElement, DuoyunEmptyElement, DuoyunFilePickerElement, DuoyunFlowElement, DuoyunFlowCanvasElement, DuoyunFormElement, DuoyunFormItemElement, DuoyunFormItemInlineGroupElement, DuoyunGestureElement, DuoyunHeadingElement, DuoyunHelpTextElement, DuoyunIconsElement, DuoyunImagePreviewElement, DuoyunInputElement, DuoyunInputCaptureElement, DuoyunInputGroupElement, DuoyunKeyboardAccessElement, DuoyunLegendElement, DuoyunLightRouteElement, DuoyunLineChartElement, DuoyunLinkElement, DuoyunListElement, DuoyunListItemElement, DuoyunLoadingElement, DuoyunMapElement, DuoyunMeterElement, DuoyunModalElement, DuoyunMoreElement, DuoyunMoreSlotElement, DuoyunOptionsElement, DuoyunPageLoadbarElement, DuoyunPaginationElement, DuoyunParagraphElement, DuoyunPickerElement, DuoyunPlaceholderElement, DuoyunPopoverElement, DuoyunPopoverGhostElement, DuoyunProgressElement, DuoyunRadioElement, DuoyunRadioGroupElement, DuoyunRateElement, DuoyunReflectElement, DuoyunResultElement, DuoyunRouteElement, DuoyunScatterChartElement, DuoyunSelectElement, DuoyunSelectionBoxElement, DuoyunSelectionBoxMaskElement, DuoyunShortcutRecordElement, DuoyunSideNavigationElement, DuoyunSliderElement, DuoyunSpaceElement, DuoyunStatisticElement, DuoyunStatusLightElement, DuoyunSwitchElement, DuoyunTableElement, DuoyunTabPanelElement, DuoyunTabsElement, DuoyunTagElement, DuoyunTextMaskElement, DuoyunTimelineElement, DuoyunTimePanelElement, DuoyunTimePickerElement, DuoyunTitleElement, DuoyunToastElement, DuoyunTooltipElement, DuoyunTreeElement, DuoyunUnsafeElement, DuoyunUseElement, DuoyunWaitElement,].map((C) => { const ele = new C() console.log(`create ${ele.tagName}`, document.createElement(ele.tagName)) }) } export default function Text() { const colorRef = useRef<DyColorPickerMethods>(null) const [color, changeColor] = useState<`#${string}`>('#aaa') return <Layout layout='test'> <DyParagraph> <DySpace size='large'> <DyButton onClick={() => colorRef.current?.showPicker()}>Open Color Picker</DyButton> <DyColorPicker ref={colorRef} value={color} onchange={(e: CustomEvent) => changeColor(e.detail)}></DyColorPicker> </DySpace> </DyParagraph> <DyCard style={{ width: '300px' }} avatar="https://api.dicebear.com/5.x/bottts-neutral/svg" preview="https://picsum.photos/400/300" header={`This is Card`} detail={`CE`} actions={[{ text: "Action1", handle: console.log }, { text: "Action2", handle: console.log }, { text: "Action3", handle: console.log }, { text: "Action4", handle: console.log }, { text: "Action5", handle: console.log }]} > Fugiat do laboris ad officia in anim qui mollit nulla reprehenderit pariatur anim sunt. </DyCard> {/* <DyActionText>DyActionText</DyActionText> */} {/* <DyActiveLink>DyActiveLink</DyActiveLink> */} {/* <DyAlert /> */} {/* <DyAreaChart /> */} {/* <DyAvatar /> */} {/* <DyAvatarGroup /> */} {/* <DyBanner /> */} {/* <DyBarChart /> */} {/* <DyBreadcrumbs /> */} {/* <DyButton>DyButton</DyButton> */} {/* <DyCalendar /> */} {/* <DyCard /> */} {/* <DyCarousel /> */} {/* <DyCascader /> */} {/* <DyCascaderPicker /> */} {/* <DyChartTooltip /> */} {/* <DyChartZoom /> */} {/* <DyCheckbox /> */} {/* <DyCheckboxGroup /> */} {/* <DyCoachMark /> */} {/* <DyCodeBlock /> */} {/* <DyContextmenu /> */} {/* <DyCollapse /> */} {/* <DyCollapsePanel /> */} {/* <DyColorPanel /> */} {/* <DyColorPicker /> */} {/* <DyCompartment /> */} {/* <DyCopy /> */} {/* <DyDatePanel /> */} {/* <DyDatePicker /> */} {/* <DyDateRangePanel /> */} {/* <DyDateRangePicker /> */} {/* <DyDivider /> */} {/* <DyDonutChart /> */} {/* <DyDrawer /> */} {/* <DyDropArea /> */} {/* <DyEmpty /> */} {/* <DyFilePicker /> */} {/* <DyFlow /> */} {/* <DyFlowCanvas /> */} {/* <DyForm /> */} {/* <DyFormItem /> */} {/* <DyFormItemInlineGroup /> */} {/* <DyGesture /> */} {/* <DyHeading /> */} {/* <DyHelpText /> */} {/* <DyIcons /> */} {/* <DyImagePreview /> */} {/* <DyInput /> */} {/* <DyInputCapture /> */} {/* <DyInputGroup /> */} {/* <DyKeyboardAccess /> */} {/* <DyLegend /> */} {/* <DyLightRoute /> */} {/* <DyLineChart /> */} {/* <DyLink /> */} {/* <DyList /> */} {/* <DyListItem /> */} {/* <DyLoading /> */} {/* <DyMap /> */} {/* <DyMeter /> */} {/* <DyModal /> */} {/* <DyMore /> */} {/* <DyMoreSlot /> */} {/* <DyOptions /> */} {/* <DyPageLoadbar /> */} {/* <DyPagination /> */} {/* <DyParagraph /> */} {/* <DyPicker /> */} {/* <DyPlaceholder /> */} {/* <DyPopover /> */} {/* <DyPopoverGhost /> */} {/* <DyProgress /> */} {/* <DyRadio /> */} {/* <DyRadioGroup /> */} {/* <DyRate /> */} {/* <DyReflect /> */} {/* <DyResult /> */} {/* <DyRoute /> */} {/* <DyScatterChart /> */} {/* <DySelect /> */} {/* <DySelectionBox /> */} {/* <DySelectionBoxMask /> */} {/* <DyShortcutRecord /> */} {/* <DySideNavigation /> */} {/* <DySlider /> */} {/* <DySpace /> */} {/* <DyStatistic /> */} {/* <DyStatusLight /> */} {/* <DySwitch /> */} {/* <DyTable /> */} {/* <DyTabPanel /> */} {/* <DyTabs /> */} {/* <DyTag /> */} {/* <DyTextMask /> */} {/* <DyTimeline /> */} {/* <DyTimePanel /> */} {/* <DyTimePicker /> */} {/* <DyTitle /> */} {/* <DyToast /> */} {/* <DyTooltip /> */} {/* <DyTree /> */} {/* <DyUnsafe /> */} {/* <DyUse /> */} {/* <DyWait /> */} </Layout> }

在 <dy-route> 中使用 React 组件

<dy-route> 只支持渲染 TemplateResult

const routes = { about: { pattern: '/about', title: `About`, getContent(_, ele) { return html`<p-about></p-about>`; }, }, } satisfies RoutesObject;

要渲染 React 组件需要手动挂载到 <dy-route> 上:

function renderReactNode(ele: any, node: ReactNode) { ele.react?.unmount(); ele.react = createRoot(ele); ele.react.render(node); } const routes = { about: { pattern: '/about', title: `About`, getContent(_, ele) { renderReactNode(ele, <About />); }, }, } satisfies RoutesObject;

在 Property 上使用 React 组件

一些元素支持自定义渲染内容,例如 <dy-card>header

function Page() { return <DyCard header={html`<div>No.</div>`}></DyCard>; }

如果要渲染 React 组件,则需要先渲染到 HTMLElement 上,可以通过自定义 Hooks 实现:

function useReactNode(node: ReactNode) { const ref = useRef<{ root: Root; container: HTMLElement }>(); useEffect(() => () => ref.current?.root.unmount(), []); if (ref.current) { ref.current.root.render(node); return ref.current.container; } const container = document.createElement('div'); container.style.display = 'contents'; const root = createRoot(container); ref.current = { root, container }; root.render(node); return container; } function Page() { return <DyCard header={useReactNode(<>No</>)}></DyCard>; }

Vue

DuoyunUI 也导出了 Vue 组件,使用和 React 一样,唯一的区别是路径将 react 改成 vue, 另外需要在 Vue 配置文件中指定自定义元素:

{ compilerOptions: { isCustomElement: (tag) => tag.startsWith('dy-'); } }

在 Vue 中也支持直接写自定义元素,但是要区分是 Attribute 还是 Property:

<script setup lang="ts"> import DySpace from 'duoyun-ui/vue/DySpace.vue' import DyButton from 'duoyun-ui/vue/DyButton.vue' import DyCard from 'duoyun-ui/vue/DyCard.vue' import DyColorPicker from 'duoyun-ui/vue/DyColorPicker.vue' import DyParagraph from 'duoyun-ui/vue/DyParagraph.vue' import type { HexColor } from 'duoyun-ui/lib/color' const colorElement = ref<InstanceType<typeof DyColorPicker>>(); const cardActions = ref([{ text: 'Action1', handle: console.log }, { text: 'Action2', handle: console.log }, { text: 'Action3', handle: console.log }, { text: 'Action4', handle: console.log }]); const cardHeader = ref('This header'); const color = ref<HexColor>('#f0f'); const clickHandle = () => { cardActions.value = cardActions.value.reverse() cardHeader.value = [...cardHeader.value].reverse().join('') } const onChange = (e: CustomEvent<HexColor>) => { color.value = e.detail } </script> <template> <DyParagraph> <DySpace> <DyButton @click="() => colorElement?.showPicker()">Open Color Picker</DyButton> <DyColorPicker ref=colorElement :value="color" alpha @change="onChange"></DyColorPicker> <dy-color-picker :value="color" alpha @change="onChange"></dy-color-picker> </DySpace> </DyParagraph> <DySpace> <DyCard @click="clickHandle" class="card" avatar="https://api.dicebear.com/5.x/bottts-neutral/svg" preview="https://picsum.photos/400/300" :header="cardHeader" :detail="`CE`" :actions="cardActions">Fugiat do laboris ad officia in anim qui mollit nulla reprehenderit pariatur anim sunt.</DyCard> <dy-card @click="clickHandle" class="card" avatar="https://api.dicebear.com/5.x/bottts-neutral/svg" preview="https://picsum.photos/400/300" .header="cardHeader" .detail="`CE`" .actions="cardActions">Fugiat do laboris ad officia in anim qui mollit nulla reprehenderit pariatur anim sunt.</dy-card> </DySpace> </template> <style scoped> .card { width: 300px; } </style>

Svelte

DuoyunUI 没有重导出为 Svelte 组件,直接使用自定义元素即可:

<script lang="ts"> import "duoyun-ui/svelte/button"; import "duoyun-ui/svelte/card"; import "duoyun-ui/svelte/paragraph"; import "duoyun-ui/svelte/space"; import "duoyun-ui/svelte/color-picker"; import type { DuoyunColorPickerElement } from "duoyun-ui/svelte/color-picker"; let colorElement: DuoyunColorPickerElement | undefined; let cardActions = [ { text: "Action1", handle: console.log }, { text: "Action2", handle: console.log }, { text: "Action3", handle: console.log }, { text: "Action4", handle: console.log }, ]; let cardHeader = "This header"; let color: `#${string}` = "#f0f"; const clickHandle = () => { cardActions = cardActions.reverse(); cardHeader = [...cardHeader].reverse().join(""); }; const onChange = (e: CustomEvent) => { color = e.detail; }; </script> <div> <dy-paragraph> <dy-space> <dy-button on:click={() => colorElement?.showPicker()}> Open Color Picker </dy-button> <dy-color-picker bind:this={colorElement} on:change={onChange} value={color} alpha ></dy-color-picker> </dy-space> </dy-paragraph> <dy-card on:click={clickHandle} class="card" avatar="https://api.dicebear.com/5.x/bottts-neutral/svg" preview="https://picsum.photos/400/300" header={cardHeader} detail={`CE`} actions={cardActions} > Fugiat do laboris ad officia in anim qui mollit nulla reprehenderit pariatur anim sunt. </dy-card> </div> <style> .card { width: 240px; } </style>

NOTE

使用 SvelteKit 请确保 svelte 安装成 dependencies 而非 devDependencies,否则类型不能成功导入; 如果编译出现“Unexpected token 'export'”的错误请在 vite.config.ts 中添加下面代码:

{ ssr: { noExternal: ['@mantou/gem', 'duoyun-ui']; } }

SSR

DuoyunUI 不支持 SSR,确切的说是 Next/Nuxt/Svelte 不支持自定义元素 SSR,自定义元素的 ShadowDOM 是运行时生成, 为了能在服务端正确运行,在前端代码的入口位置导入 @mantou/gem/helper/ssr-shim

  • Next.js: pages/_app.tsx
  • Nuxt.js: app.config.ts
  • SvelteKit: src/hooks.server.ts

如果要使用 DuoyunUI 的路由,可以使用 <dy-light-route>。为了避免首屏排版错误添加下面全局样式:

:not(:defined) { display: none; }