属性 / 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() 方法来处理异步操作失败时的情况。