SvelteKit 2.5中如何创建内联高阶组件?以ErrorHelper为例
在SvelteKit 2.5中封装预设属性的组件(以Flowbite-Svelte Helper为例)
需求场景
开发页面时频繁使用Flowbite-Svelte的Helper组件设置红色文本,每次都要写<Helper color="red">...</Helper>,希望封装成<ErrorHelper>...</ErrorHelper>,让它自动向Helper传递color="red"属性。
错误尝试:类继承方式
尝试用类继承实现封装,代码如下:
import { Helper } from 'flowbite-svelte'; class ErrorHelper extends Helper { constructor(vals) { const newVals = {...vals, props: {...vals.props, color: 'red'}} super(newVals); } }
这段代码在纯Svelte环境的Storybook中可以运行,但在SvelteKit项目中使用时,出现以下错误:
TypeError: Class extends value #<Object> is not a constructor or null at /src/lib/components/OnboardStep3.svelte:17:28 at Object.$$render (/node_modules/svelte/src/runtime/internal/ssr.js:156:16) at eval (/src/routes/onboard/3/+page.svelte:15:100) at Object.$$render (/node_modules/svelte/src/runtime/internal/ssr.js:156:16) at Object.default (/.svelte-kit/generated/root.svelte:48:43) at /node_modules/@sveltejs/kit/src/runtime/components/layout.svelte:5:41 at Object.$$render (/node_modules/svelte/src/runtime/internal/ssr.js:156:16) at Object.default (/.svelte-kit/generated/root.svelte:47:42) at eval (/src/routes/+layout.svelte:25:163) at Object.$$render (/node_modules/svelte/src/runtime/internal/ssr.js:156:16)
原因:Svelte组件编译后并非ES类,在SvelteKit的SSR环境下,组件导出是一个对象而非构造函数,因此无法通过class extends实现继承。
正确实现方式
方式一:基础封装(固定预设属性+透传其他属性)
创建src/lib/components/ErrorHelper.svelte文件:
<script lang="ts"> import { Helper } from 'flowbite-svelte'; // 透传用户传入的其他属性(如class、id等) export let ...$props; </script> <Helper color="red" {...$props}> <!-- 传递组件的子内容 --> <slot /> </Helper>
使用方式:
<script lang="ts"> import ErrorHelper from '$lib/components/ErrorHelper.svelte'; </script> <ErrorHelper>这是红色的错误提示文本</ErrorHelper> <!-- 也可以额外传递其他属性 --> <ErrorHelper class="mt-4">带外边距的错误提示</ErrorHelper>
方式二:可灵活覆盖的封装
如果需要允许用户临时覆盖预设的color属性,或者传递更多自定义参数,可以调整代码:
<script lang="ts"> import { Helper } from 'flowbite-svelte'; // 默认值设为red,用户可传入其他值覆盖 export let color = 'red'; // 透传所有其他属性 export let ...$props; </script> <Helper {color} {...$props}> <slot /> </Helper>
使用方式:
<!-- 使用默认红色 --> <ErrorHelper>默认红色提示</ErrorHelper> <!-- 临时覆盖为橙色 --> <ErrorHelper color="orange">橙色提示</ErrorHelper>
方式三:通用高阶组件封装(适合批量预设)
如果需要封装多个类似的预设组件(如SuccessHelper、WarningHelper),可以写一个通用的高阶组件函数:
// src/lib/utils/createHelper.ts import { Helper } from 'flowbite-svelte'; import type { Component, SvelteComponentTyped } from 'svelte'; export function createHelper(color: string): Component<SvelteComponentTyped> { return { render: (props, { slot }) => { return Helper.render({ ...props, color }, { slot }); } }; }
然后创建具体的预设组件:
<!-- src/lib/components/ErrorHelper.svelte --> <script lang="ts"> import { createHelper } from '$lib/utils/createHelper'; const ErrorHelper = createHelper('red'); </script> <ErrorHelper {...$props}> <slot /> </ErrorHelper>
这种方式适合批量创建不同预设的组件,减少重复代码。
内容的提问来源于stack exchange,提问作者Tyler Collier
相关产品推荐
相关产品推荐

