svelte api docs走读笔记。
组件指令(Component Directives)
组件可以使用createEventDispatcher
来派发事件。组件的事件可以在组件的使用界面上被捕获:
<SomeComponent on:whatever={handler}/>
,如果不想捕获事件,也可以转发:<SomeComponent on:whatever/>
。
组件的props也可以绑定到一个变量:bind:property={variable}
。例子:<Keypad bind:value={pin}/>
。另一个例子:
<ShoppingCart bind:this={cart}/>
<button on:click={() => cart.empty()}>
Empty shopping cart
</button>
注意,初次渲染的时候cart是undefined,所以需要在on:click的时候返回函数折衷一下:() => cart.empty()
。
<slot>
组件不仅有props/properties,还可以有子节点:
<!-- App.svelte -->
<Widget>
<p>this is some child content</p>
</Widget>
其实可以把子节点看成是组件的一个额外的输入参数。比如上面的<p>this is some child content</p>
可以看成是组件<Widget>
的一个额外输入参数。由于组件是自定义的,所以可以控制如何处理这个额外的输入参数,就像一个参数可以被函数任意使用一样:
<!-- Widget.svelte -->
<div>
<slot>
this will be rendered if someone does <Widget/>
</slot>
</div>
<slot>...</slot>
中的内容,被视为slot的默认值。
也可以通过<slot name="name">
给这个额外的参数加上名字,这样做的好处是可以有多个被命名的额外参数,提供更大的灵活性:
<!-- Widget.svelte -->
<div>
<slot name="header">No header was provided</slot>
<p>Some content between header and footer</p>
<slot name="footer"></slot>
</div>
上面的例子中有两个命名的slot,分别是header和footer。
除了可以被命名以外,slot还可以带参数(如果把slot比作一个变量,那么这个变量的类型也可以是函数,并且这个函数可以接收额外的参数,需要在组件的使用地指定)
<!-- App.svelte -->
<FancyList {items}>
<div slot="item" let:item={item}>{item.text}</div>
<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList>
<!-- FancyList.svelte -->
<ul>
{#each items as item}
<li class="fancy">
<slot name="item" item={item}></slot>
</li>
{/each}
</ul>
<slot name="footer"></slot>
上述的代码中,有一个名为item的slot,可以带 一个名为item的参数…… 所在在slot的使用地,需要指定参数:<div slot="item" let:item={item}>
。(如果使用的时候没有设置参数该怎么办?)
svelte的自带组件
Svelte中有一些特别的预定义组件:
<svelte:self>
,用来递归产生当前组件。使用此组件要注意设置判断条件,否则会陷入无限循环。<svelte:component>
,用来动态加载一个组件,比如<svelte:component this={currentSelection.component} foo={bar}/>
<svelte:window>
,指代DOM的window,暴露有若干属性。<svelte:body>
,指代DOM的body元素<svelte:head>
,指代DOM的head元素<svelte:options>
,用来指定编译时候的一些选项
运行时(Runtime)
svelte
模块,包含生命周期管理相关的调度函数,以及context相关函数,还有createEventDispatchersvelte/store
模块,一切跟store相关的东西svelte/motion
模块,一切跟motion相关的操作svelte/transition
模块,一切跟转场相关的事物svelte/animate
模块,一些跟动画有关的功能svelte/easing
模块,一些跟动作平滑相关的函数svelte/register
模块,允许在nodejs中使用require('svelte/register')
来导入组件,无需打包器的协助
客户端组件API
客户端组件是指编译的时候指定generate: 'dom'
(默认)选项的组件。
实例化一个组件const component = new Component(options)
,具体:
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
// assuming App.svelte contains something like
// `export let answer`:
answer: 42
}
});
选项:
- target,默认none,An HTMLElement to render to. This option is required
- anchor,默认null,A child of target to render the component immediately before
- props,默认{},An object of properties to supply to the component
- hydrate,默认false,See below
- intro,默认false,If true, will play transitions on initial render, rather than waiting for subsequent state changes
组件有若干方法:
$set(props)
,设置组件的props,异步更新组件$on(event, callback)
,增加事件回调$destroy()
,销毁组件component.prop
,访问组件的propcomponent.prop = value
,更新组件的prop,同步更新
自定义元素API
Svelte支持web的自定义元素(custom element)。通过<svelte:options>
设置customElement: true
可以把一个组件编译为自定义元素。自定义元素和组件的区别在于,自定义元素浏览器原生支持,可以自由加载,比如:
document.body.innerHTML = `
<my-element>
<p>This is some slotted content</p>
</my-element>
`;
需要在<svelte:options>
为自定义元素指定一个tag。
<svelte:options tag="my-element">
<script>
export let name = 'world';
</script>
<h1>Hello {name}!</h1>
<slot></slot>
如果tag指定为{null}
,那么使用自定义组件的时候必须指定一个元素名:
import MyElement from './MyElement.svelte';
customElements.define('my-element', MyElement);
通过accessors
选项可以调节自定元素的props的可见性。自定义组件使用起来有一些其他考量,具体请翻阅文档。
服务端组件API
服务端组件API用于服务端渲染,所生成的是静态的HTML和CSS。组件的render
函数可以用于此目的:
const result = Component.render(...)
Render会生成一个对象,其属性保存有生成的html, head, css属性。其中head
包含了在所有在<svelte:head>
中指定的内容。
编译时(CompileTime)
一般情况下,开发者不用插手Svelte编译时的行为,但是理解编译时候的行为,有时候会能帮上忙。
svelte.compile
编译一个组件,并生成相应的各种成分的代码:
result: {
js,
css,
ast,
warnings,
vars,
stats
} = svelte.compile(source: string, options?: {...})
svelte.parse
和svelte.compile
类似,不过返回的是AST。svelte.walk
可以用来遍历这个AST。
svelte.preprocess
提供一些钩子函数,可以对组件源码进行预处理,编写插件的时候大有用处。
svelte.VERSION
返回Svelte的版本(在package.json)里面记录的。
(完)