
在个人项目中尝试过Svelte之后,我想继续进行下去,并在项目中采用更大的框架。 为此,我编写了一个组件svelte-atoms 。 作为基础,我在React上使用了UI工具包,我们在工作中使用了它。
我学了Svelte哪些技术,请仔细阅读。
本文假定您已经熟悉Svelte的基本概念。 如果没有,建议您先阅读我以前的文章:
斯维尔特(Svelte)一生
在Svelte 3上开发游戏
该库处于主动修订阶段。 仍然缺少某些组件,可访问性问题尚未解决,并且并非所有错误都已修复。 现在,我正在对此鲸做一个项目,以了解在战斗模式下首先需要改进的地方。
因此,我通过在Svelte中编写组件库中学到了什么。
1.使用class属性
如果要将class属性添加到组件的参数中,则会出现错误,因为该词是javascript本身保留的。
<script> export let class = ''; </script>
您可以使用内部的Svelte API解决此问题。 $$ props变量包含传递给组件的所有属性。 在父组件中,您可以传递class属性
<Component class="someClass" />
然后在组件本身中,通过$$ props变量设置类。
<div class={$$props.class} />
REPL中的示例
2.样式子组件
Svelte使用样式隔离。 如果您在组件中添加了一个类,则将向其中添加一个哈希,该哈希将对于您的组件而言是唯一的,并且不会在任何地方泄漏。 但是,如果您需要设置子组件的样式,该怎么办? 给他上课并给父母开一些样式是合乎逻辑的。 使用伪指令global()可以很简单地解决这个问题。
<script> import Component from "./Component.svelte"; </script> <div class="parent"> <Component class="childClass" /> </div> <style> .parent :global(.childClass) { color: red; } </style>
REPL中的示例
通过这种方法,您仍然可以获得孤立的样式,但这适用于子组件的整个层次结构
3.所有事件的处理者
Svelte组件必须支持该事件,以便可以为其分配外部处理程序。 规定事件的所有选项很累。 相反,您可以编写一个通用处理程序,该处理程序将查找传递给组件的事件处理程序并将其添加到我们的组件中。 我在AlexxNB的Svelte -chota库中 发现了这个想法。
例子 <script> import { current_component, bubble, listen } from "svelte/internal"; function getEventsAction(component) { return node => { const events = Object.keys(component.$$.callbacks); const listeners = []; events.forEach(event => listeners.push(listen(node, event, e => bubble(component, e))) ); return { destroy: () => { listeners.forEach(listener => listener()); } }; }; } const events = getEventsAction(current_component); export let value; </script> <input use:events {value} />
REPL中的示例
此方法并不完全合法,因为它使用内部的Svelte API(可能会更改)。 我希望将来会支持on: * Issue指令将在github上添加
4.插槽检测
如果您需要确定插槽中的内容是否已转移,那么我可以为您提供两个选择。
第一种方式,合法
如果未传输内容,则插槽具有回退状态。 将折叠后衬制作为变量后,我们可以检测到插槽。
<script> let footerRef = null; $: isFooterExists = Boolean(footerRef); </script> <slot name="footer"> <div bind:this={footerRef} /> </slot> {isFooterExists ? ' ' : ' '}
第二种方式,半合法
您可以使用内部的Svelte API
const isFooterExists = Boolean($$props.$$slots && $$props.$$slots.footer);
REPL中的示例
5.门户
Svelte不像React那样接受门户,但是它很简单。 您可以为此使用DOM API。
<script> import { onMount } from "svelte"; let ref; onMount(() => { document.body.appendChild(ref); return () => { document.body.removeChild(ref); }; }); </script> <div> <div bind:this={ref}>content</div> </div>
要安装组件,我们将其转移到主体,然后在移除时,移除门户。
重要说明:将门户包裹在div中,否则Svelte可能会在卸载时错误地卸下组件。
6.动画
Svelte有大量现成的动画,可能对您的工作有用。 为组件的外观和消失设置动画非常容易。 但是为一个块设置动画可能会减慢整个页面的删除速度。 Svelte将等待动画完成,然后再从树中删除组件。 为避免这种情况,请使用本地指令。
教程示例
7.命名的插槽和组件
不幸的是,您不能立即将组件传输到命名插槽。 在github上发布
<Component> <Child slot='footer'/> </Component>
要将组件传输到命名插槽,请将其包装在div或任何其他html标签中。
<Component> <div slot='footer'> <Child /> </div> </Component>
8.获取组件属性列表
如果需要获取从组件导出的属性的列表,则可以使用以下构造:
<script> import Component from './Component.svelte'; const [_, ...props] = Object.getOwnPropertyNames(Component.prototype); </script> {JSON.stringify(props)}
我从PaulMaly那里得到了这个主意。
9.双面装订
在React上进行开发之后,双向绑定的概念似乎令人生畏,但这只是乍一看。 结果,您的应用程序将看起来更加简洁,并且使您摆脱了一堆处理程序。 您既可以使用常规变量,也可以将其存储为存储。
<script> import Input from "./Input.svelte"; import { writable } from "svelte/store"; let letValue = "test let"; const storeValue = writable("test store"); </script> <Input bind:value={letValue} /> <Input bind:value={$storeValue} />
REPL中的示例
10.可编辑的内容
如果需要使元素的内容可编辑,则可以使用contenteditable指令并将值绑定到变量中。
<script> let value = "Edit me"; </script> <div contenteditable="true" bind:textContent={value}>{value}</div> <div>Value: {value}</div>
REPL中的示例
元件尺寸
好吧,那里没有React。 对比实现相同的Svelte和React上的组件代码行数。 代码和样式都考虑在内。

演示库
源代码
如果您发现错误或想要提出建议,请创建一个问题
聚苯乙烯
2020年2月22日将在莫斯科举行Svelte Russian Meetup#1。 详细信息和电报中向俄罗斯社区团体Svelte的官方公告: @sveltejs
我邀请大家参加!