前两讲所探讨的关于组件的状态(反应性)以及组件向子组件传递参数,今天要进入模板逻辑
大家知道,HTML
没有表达逻辑的方法,比如条件和循环。 Svelte
是可以的。
一、if块 为了有条件地渲染一些标记,我们将它包装在一个 if
块中:
1 2 3 4 5 6 7 8 9 10 11 {#if user.loggedIn} <button on:click ={toggle} > Log out </button > {/if} {#if !user.loggedIn} <button on:click ={toggle} > Log in </button > {/if}
上面看着是不是以前使用过?在双向绑定之前的一段时间内,大家都是使用js的模板库来实现UI的渲染,它十分接近一些以往非常流行的 Handlebars 或者 Mustache 模板语言。
试试看——更新组件,然后点击按钮。
完整的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <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 块 还是上面的例子,由于这两个条件 - if user.logged In 和 if !user.logged In - 是互斥的,我们可以通过使用 else 块来稍微简化这个组件:
1 2 3 4 5 6 7 8 9 {#if user.loggedIn} <button on:click ={toggle} > Log out </button > {:else} <button on:click ={toggle} > Log in </button > {/if}
#
字符代表 块开始 标记。/
字符代表 块结束 标记。而 {:else}
中的 :
字符,则表示 块连续 标记。不用担心,至此你几乎已经学完 Svelte
为 HTML
添加的所有语法了。
三、Else-If 块 看下面的例子,可以使用else if将多个条件 “连接” 在一起:
1 2 3 4 5 6 7 {#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 块 如果您需要遍历数据列表,请使用 each 块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <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 of YouTube</h1 > <ul > {#each cats as cat} <li > <a target ="_blank" href ="https://www.youtube.com/watch?v={cat.id}" > {cat.name} </a > </li > {/each}</ul >
表达式 cats是一个数组,遇到数组或类似于数组的对象 (即具有length 属性)。你都可以通过 each […iterable]遍历迭代该对象。
你也可以将index 作为第二个参数(key),类似于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <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 of YouTube</h1 > <ul > {#each cats as cat, i} <li > <a target ="_blank" href ="https://www.youtube.com/watch?v={cat.id}" > {i + 1}: {cat.name} </a > </li > {/each}</ul >
只要你愿意,还可以使用解构语法each cats as { id, name }, i,
也即是用id
、name
来代替cat.id
、cat.name
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <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 of YouTube</h1 > <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 >
REPL
五、拥有key的each块 默认情况下,当您修改 each
块的值时,它将在块的末尾添加和删除项目,并更新任何已更改的值。 不过那可能不是你想要的。
说明原因比解释更容易。 单击“删除第一件事”按钮几次,注意会发生什么:它不会删除第一个 <Thing>
组件,而是删除最后一个 DOM
节点。 然后它会更新剩余 DOM
节点中的名称值,但不会更新表情符号。
还是看实例吧,不然光看文字描述会有点懵。
相反,我们只想删除第一个 <Thing>
组件及其 DOM
节点,而其他不受影响。
为此,我们为每个块指定一个唯一标识符(“key”)
:
1 2 3 {#each things as thing (thing.id)} <Thing name ={thing.name}/ > {/each}
这个 (thing.id)
告知 Svelte
如何计算变化的地方。
你可以将任何对象用作 key 来使用,就像Svelte 用 Map 在内部作为key一样,换句话说,你可以用 (thing) 来代替 (thing.id)作为 key 值。但是,使用字符串或者数字作为 key 值通常更安全,因为这能确保它的唯一性,例如,使用来自API服务器的新数据进行更新时。
如果熟悉Vue互助angular的会对这个感到熟悉,思路相似,或者说站在巨人的肩上。
六、await 块 很多Web应用程序都可能在某个时候有需要处理异步数据的需求。使用 Svelte
在标签中使用 await
处理 promises
数据亦是十分容易:
1 2 3 4 5 6 7 {#await promise} <p > ...waiting</p > {:then number} <p > The number is {number}</p > {:catch error} <p style ="color: red" > {error.message}</p > {/await}
promise总是获取最新的信息,这使得你无需关心 rece 状态。
如果你的知道你的 promise
返回错误,则可以忽略 catch
块。如果在请求完成之前不想程序执行任何操作,也可以忽略第一个块。
1 2 3 {#await promise then value} <p > the value is {value}</p > {/await}
REPL
七、key 块 Key
块在表达式的值更改时销毁并重新创建其内容。如果您希望元素在值更改时播放其过渡,这很有用。
语法
1 2 3 {#key value} <div transition:fade > {value}</div > {/key}
如果key
包裹着组件使用,将导致组件被重新实例化和重新初始化。
1 2 3 {#key value} <Component /> {/key}
按照对key块的描述我们使用一个交互实例来看
REPL
上面使用if
块和key
块进行了对比,通过点击按钮观察,只有if
块只有第一次的数字改变会有fly
动画效果,后面都不在有,而key
块则一致有效果。这说明只要 num 的值改变了,key 块内的元素都会被销毁且重新渲染。
总结 本讲把所有的模板逻辑的都讲了一遍,内容有点多,实际使用最多的是if
块和each
块。
如果你习惯了react的jsx或者Vue的模板语法,会觉得这个感觉好奇怪,不过你完全有可能一开始不太适应这种模板语言,甚至是非常别扭。
你学习了这些让你知道都有哪些可以使用的,实际中你可以使用插件来辅助你,这里推荐vscode 插件Svelte 3 Snippets
当然这个插件肯定不是包含所有的模板和其他的api,新的api加入插件的更新会延迟。