Svelte文档走读(二)

Tue 08 October 2019 / In categories Notes

Svelte

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相关函数,还有createEventDispatcher
  • svelte/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,访问组件的prop
  • component.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.parsesvelte.compile类似,不过返回的是AST。svelte.walk可以用来遍历这个AST。

svelte.preprocess提供一些钩子函数,可以对组件源码进行预处理,编写插件的时候大有用处。

svelte.VERSION返回Svelte的版本(在package.json)里面记录的。

(完)

Load Disqus Comments