[svelte]属性和逻辑块

时间:2024-04-21 13:48:37

属性 / Default values • Svelte 教程 | Svelte 中文网

属性
Declaring props

到目前为止,我们只处理了内部状态——也就是说,这些值只能在给定的组件中访问。 在任何实际应用程序中,都需要将数据从一个组件向下传递到其子组件。为此,我们需要声明属性,通常缩写为“props”。在 Svelte 中,我们使用关键字export来做到这一点

app.svelte

<script>
	import Nested from './Nested.svelte';
</script>

<Nested answer={42}/>

Nested.svelte

<script>
	 export let answer;
</script>

<p>The answer is {answer}</p>

可以将export删除来看前后对比

一个会输出The answer is 42,一个是The answer is undefined

Default values

我们重新修改一下代码

app.svelte

<script>
	import Nested from './Nested.svelte';
</script>

<Nested answer={42}/>
<Nested/>

Nested.svelte

<script>
	export let answer = 'a mystery';
</script>

<p>The answer is {answer}</p>

那这样子最后的输出是什么

The answer is 42

The answer is a mystery

前面一个42是,因为引入了answer的定义值

后面因为没有了,就变成Nested中的默认值了

属性传递

如果组件中含有一个对象属性,可以利用...语法将它们传到一个组件上,这样子就不用一个一个的指定

相反,如果你需要引用传递到组件中的所有道具,包括未使用export声明的道具,可以利用$$props 直接获取。但通常不建议这么做,因为Svelte难以优化,但在极少数情况下很有用。

Info.svelte

<script>
	export let name;
	export let version;
	export let speed;
	export let website;
</script>

<p>
	The <code>{name}</code> package is {speed} fast.
	Download version {version} from <a href="https://www.npmjs.com/package/{name}">npm</a>
	and <a href={website}>learn more here</a>
</p>

app.svelte

<script>
	import Info from './Info.svelte';

	const pkg = {
		name: 'svelte',
		version: 3,
		speed: 'blazing',
		website: 'https://svelte.dev'
	};
</script>

/*<Info name={pkg.name} version={pkg.version} speed={pkg.speed} website={pkg.website}/>*/
<Info {...pkg}/>
逻辑
if

HTMl没有表达逻辑的方式,但if可以被包装在一个块中

比如下面这样子

<script>
	let user = { loggedIn: false };

	function toggle() {
		user.loggedIn = !user.loggedIn;
	}
</script>

{#if user.loggedIn}
<button on:click={toggle}>
	Log out
</button>
{/if}

{#if !user.loggedIn}
	<button on:click={toggle}>
		Log in
	</button>
{/if}
else

因为上面代码中的两个条件是互斥的,所以其实可以用else来简化组件

<script>
	let user = { loggedIn: false };

	function toggle() {
		user.loggedIn = !user.loggedIn;
	}
</script>

{#if user.loggedIn}
	<button on:click={toggle}>
		Log out
	</button>
{:else}
	<button on:click={toggle}>
		Log in
	</button>
{/if}

#开始,/结束,: 中间插入

else if

将多个条件链接在一起的时候就需要 else if 上场了

<script>
	let x = 7;
</script>

{#if x > 10}
	<p>{x} is greater than 10</p>
{:else if 5 > x}
	<p>{x} is less than 5</p>
{:else}
	<p>{x} is between 5 and 10</p>
{/if}
each遍历

遇见需要进行遍历的数据列表

遇到数组或类似于数组的对象 (即具有length 属性)。都可以通过 each [...iterable]遍历迭代该对象。

<script>
	let cats = [
		{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
		{ id: 'z_AbfPXTKms', name: 'Maru' },
		{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
	];
</script>

<h1>The Famous Cats </h1>


<ul>
	{#each cats as cat}
		<li><a target="_blank" href="https://www.baidu.com/">
			{cat.name}
		</a></li>
	{/each}
</ul>


<ul>
	{#each cats as { id, name }, i}
		<li><a target="_blank" href="https://www.youtube.com/watch?v={id}">
			{i + 1}: {name}
		</a></li>
	{/each}
</ul>
each添加key值

一般来说,当你修改each 块中的值时,它将会在 尾端 进行添加或删除条目,并更新所有变化, 这可能不是你想要的效果。

Thing.svelte

<script>
	// `current` is updated whenever the prop value changes...
	export let current;

	// ...but `initial` is fixed upon initialisation
	const initial = current;
</script>

<p>
	<span style="background-color: {initial}">initial</span>
	<span style="background-color: {current}">current</span>
</p>

<style>
	span {
		display: inline-block;
		padding: 0.2em 0.5em;
		margin: 0 0.2em 0.2em 0;
		width: 4em;
		text-align: center;
		border-radius: 0.2em;
		color: white;
	}
</style>

App.svelte

<script>
	import Thing from './Thing.svelte';

	let things = [
		{ id: 1, color: '#0d0887' },
		{ id: 2, color: '#6a00a8' },
		{ id: 3, color: '#b12a90' },
		{ id: 4, color: '#e16462' },
		{ id: 5, color: '#fca636' }
	];

	function handleClick() {
		things = things.slice(1);
	}
</script>

<button on:click={handleClick}>
	Remove first thing
</button>

{#each things as thing}
	<Thing current={thing.color}/>
{/each}

可以运行上面的代码进行实例查看,尝试多次点击'Remove first thing' 按钮,这时<Thing> 组件是从尾端开始被移除,这显然不是我们想要的,我们希望是从上至下依次开始删除组件。

很明显,他直接删除的是最下面的initial,为此,我们为 each 块指定一个唯一标识符,作为 key 值:

{#each things as thing (thing.id)}
	<Thing current={thing.color}/>
{/each}

 

(thing.id) 告诉 Svelte 什么地方需要改变。

可以将任何对象用作 key 来使用,就像Svelte 用 Map 在内部作为key一样,换句话说,你可以用 (thing) 来代替 (thing.id)作为 key 值。但是,使用字符串或者数字作为 key 值通常更安全,因为这能确保它的唯一性,例如,使用来自API服务器的新数据进行更新时。

 Await

很多Web应用程序都可能在某个时候有需要处理异步数据的需求。使用 Svelte 在标签中使用 await 处理promises 数据亦是十分容易:

promise总是获取最新的信息,无需关心 rece 状态。

<script>
	let promise = getRandomNumber();

	async function getRandomNumber() {
		const res = await fetch(`tutorial/random-number`);
		const text = await res.text();

		if (res.ok) {
			return text;
		} else {
			throw new Error(text);
		}
	}

	function handleClick() {
		promise = getRandomNumber();
	}
</script>

<button on:click={handleClick}>
	generate random number
</button>

{#await promise}
	<p>...waiting</p>
{:then number}
	<p>The number is {number}</p>
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}

Promise 是 JavaScript 中用于处理异步操作的一种机制。它代表了一个异步操作的最终完成或失败,并且可以将相关的处理逻辑附加到这个操作上。

在 JavaScript 中,异步操作通常涉及到网络请求、文件读取、定时器等需要花费一定时间才能完成的任务。

传统的回调函数方式处理异步操作可能会导致回调地狱(callback hell)和难以理解的代码结构。而 Promise 则提供了一种更清晰和可靠的方式来处理异步操作。

一个 Promise 对象有三种状态:

Pending(进行中):初始状态,表示异步操作尚未完成,也未失败。

Fulfilled(已完成):表示异步操作成功完成。

Rejected(已失败):表示异步操作失败。

一个 Promise 对象可以通过调用 resolve 函数来将其状态从 pending 变为 fulfilled,也可以通过调用 reject 函数将其状态从 pending 变为 rejected。一旦状态发生改变,Promise 对象的状态就不会再改变,它的状态一旦改变,就会一直保持在当前状态,直到被处理(通过 .then() 或 .catch() 方法)。

在使用 Promise 的时候,通常会使用 .then() 方法来处理异步操作成功时的情况,使用 .catch() 方法来处理异步操作失败时的情况。