Svelte中如何两次使用<slot>元素实现代码展示组件?
创建Svelte CodeDisplay组件实现Demo与代码同步展示
刚好我之前做文档系统时也遇到过类似需求,要实现你想要的效果,核心是要同时渲染插槽内容并捕获它的HTML代码用于展示。下面是完整的实现方案:
基础版组件实现
首先创建CodeDisplay.svelte组件,利用Svelte的bind:this和反应式语句来获取渲染后的DOM结构并转为代码文本:
<script> // 用于绑定包裹插槽的DOM元素 let demoContainer; // 存储要展示的代码文本 let codeContent = ''; // 当demoContainer可用时,提取它的HTML内容 $: if (demoContainer) { codeContent = demoContainer.innerHTML.trim(); } </script> <!-- 渲染插槽内的实际内容 --> <div class="code-display__demo" bind:this={demoContainer}> <slot /> </div> <!-- 以代码形式展示内容 --> <div class="code-display__code"> <pre> <code>{codeContent}</code> </pre> </div> <style> /* 可选:添加一些样式让布局更美观 */ .code-display__demo { padding: 1rem; background: #f8f9fa; margin-bottom: 1rem; border-radius: 4px; } .code-display__code pre { background: #2d3748; color: #e2e8f0; padding: 1rem; border-radius: 4px; overflow-x: auto; } </style>
使用方式
完全按照你期望的用法即可:
<CodeDisplay> <button class="btn" style="padding: 0.5rem 1rem; background: #4299e1; color: white; border: none; border-radius: 4px;"> Button </button> </CodeDisplay>
进阶优化:支持动态Svelte模板展示
如果你的插槽里包含Svelte的动态绑定(比如{count}),上面的基础版会展示渲染后的实际值而非原始模板代码。这种情况下,可以新增一个code props让你手动传入原始代码:
<script> export let code = ''; let demoContainer; // 如果没有手动传入code,则自动提取DOM的HTML $: if (!code && demoContainer) { code = demoContainer.innerHTML.trim(); } </script> <div class="code-display__demo" bind:this={demoContainer}> <slot /> </div> <div class="code-display__code"> <pre> <code>{code}</code> </pre> </div> <!-- 样式部分和基础版一致,这里省略 -->
进阶用法示例
<script> let count = 0; const buttonCode = '<button class="btn" on:click={() => count++}>Clicked {count} times</button>'; </script> <CodeDisplay code={buttonCode}> <button class="btn" on:click={() => count++}>Clicked {count} times</button> </CodeDisplay>
额外提示
- 如果需要代码高亮,可以引入
highlight.js之类的库,在codeContent更新时调用高亮方法即可。 - 注意
innerHTML提取的是渲染后的DOM,所以如果插槽内有组件,会展示组件渲染后的HTML而非组件标签。如果需要展示组件代码,还是得通过codeprops手动传入。
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

