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