1、什么是Svelte 不知道大家曾几何时在学习或使用一个库或框架的时候,会觉得十分惊艳,并且想着要马上用于实际的项目中。如果有,那这个框架将会是Svelte.js。
在过去的一年里,Svelte一直在掀起波澜。事实上,根据Stack overflow的调查,它的欢迎程度逐渐飙升到第一位。
Svelte 是一个令人兴奋的 Web 框架,它为开发者构建 Web 应用程序提供了全新的视角。如果你已经拥有 React、Vue、Angular 或其他前端框架的开发经验,你可能会对 Svelte 感到惊喜。
在本教程中,我们将介绍:
什么是Svelte?
Svelte与其它框架的区别
什么时候应该使用Svelte
利用 Svelte 创建待办事项列表应用 TODOLIST
Svelte.js 是一个开源的JavaScript框架,通过将Svelte代码转换为流畅的UI界面,简化了Web应用程序的创建。该框架的一个关键区别是:它在编译阶段加载框架而不是用户运行时加载,因此其比 React 或 Vue 更快。
Svelte由它的架构决定运行速度。该框架将代码编译成独立的小型JavaScript模块,确保浏览器尽可能少地完成工作,从而加快加载速度。
Svelte 超快的速度背后有三个主要原因:
无虚拟DOM: Svelte在没有虚拟DOM的情况下实现了与 React 和 Vue 相同的功能。这意味着您可以在不依赖虚拟元素的情况下使用它,并获得更好的性能优势。换句话说,Svelte 在没有 DOM 的情况下直接处理代码,并将大部分代码的处理放在编译阶段去完成。
减少代码量: Svelte 将你的代码编译成体积小、不依赖框架的普通 JS 代码,让你的应用程序无论启动还是运行都变得迅速。
响应式能力: Svelte和 React一样,对数据变化做出自己的反应,它不需要浏览器做额外的工作来将组件转换为DOM操作,将数据更改呈现为JavaScript代码。
如果你掌握了JS、HTML、CSS,则学习Svelte的时候,无任何明显的学习曲线。它允许 Web 开发人员构建各种规模的 Web 应用程序,同时为访客提供可靠的用户体验和超高的性能。
Svelte与其它框架的区别:Svelte、React、Vue 的对比 Svelte与 React、Vue等等的框架对比,Svelte构建的应用程序是事先编译的,因此不必将整个框架提供给每个网站访问者。因此,用户的体验更流畅,消耗更少的带宽,这一切都感觉更快,更轻量级。
这是一个对照的图表,您可以一目了然地查看这三个框架之间的差异。
Svelte.js
React.js
Vue.js
应用性能
比React和Vue更快
比Svelte慢,比Vue略慢
比Svelte慢,但比React略快
构建
脚本编译器
DOM
Virtual DOM
平均应用大小
15 Kb
193 Kb
71 Kb
学习曲线
简单易学
相对容易学习
相对容易学习
简单来说,Svelte可以让您提高效率。通过让您使用您熟悉的语言和符号(HTML、CSS、JavaScript),即使是初学者也可以快速入门。另一方面,React 和 Vue 需要类型脚本和 JSX 技能。
除此之外,Svelte 不依赖于在运行时加载的复杂库。相反,它会编译你的代码,并加载一个比 React更小的软件包。这种体积的差异换来的是访客更快的加载时间。
与 Vue 和 React 不同,Svelte几乎不需要初始化的脚手架,因为它是使用基本的 HTML、CSS 和 JavaScript 编写的。所以,Svelte的脚本看起来类似于普通的JS。
使用Svelte.js的好处 现在我们上面表格的对比研究了Svelte与其替代方案,让我们来谈谈Svelte能成为最受欢迎的框架的原因:
更好的开发体验 :Svelte是最受欢迎的框架,因为它设置更加简单,让开发人员可以更专注写的业务代码。
模块化 CSS :默认情况下,Svelte样式的有自己的作用域,这意味着当您将Svelte文件编译时,编译器将为每个元素生成唯一的类名。这确保了不同页面展示出来的效果是独立的。
内置动画 : 在Svelte 中使用动画是一种很好的体验。它内置了强大而令人愉悦的交互功能,无需额外的软件包。
更小的体积 : 编译完成后的代码,拥有更小的体积,更快的加载速度。
什么时候应该使用Svelte.js? 坦率地说,这一切都归结为你打算用它来构建具体的项目。仅仅因为它提供了快速的性能,并不能使它成为解决您所有问题。通常,我建议在以下情况下使用 Svelte:
构建快速、响应迅速的网站 :Svelte 的小捆绑包尺寸确保您创建的任何内容都能快速运行。这使得它非常适合那些想要快速,SEO驱动的网站和卓越的网络体验的客户。
为连接性较差的设备创建 Web 应用程序 :由于 Svelte 使用的代码更少,这意味着要下载和执行的 字节数 更少,因此非常适合构建适用于 网络 或 设备性能 较差的 应用程序。
设计交互式页面 :动画和过渡内置于 Svelte 中。开发人员可以使用svelte/animate模块创建交互式内容,这是让访问者与网站保持互动的好方法,而且并不会影响加载速度和SEO。
Svelte.js有很大的学习曲线吗? Svelte是新手编码初学者的完美平台。只需一个HTML / CSS和JavaScript技能组合,您就可以从头开始构建您的第一个网站,而无需额外的知识。
这使得学习曲线非常小,不像它的大多数替代方案。除此之外,Svelte 还提供可靠的学习资源,确保您在短短几天内掌握细节,而不是像 React、Vue 或 Angular 那样的数周或数月。
Svelte.js入门 到现在为止,我相信您已经想蠢蠢欲动,并开始写Svelte代码了。
为此,我准备了一个初学者教程,向您展示如何使用 Svelte 组件创建待办事项列表。我们将构建一个交互式表单,您可以在其中将待办事项标记为已完成,也可以将不想要的待办事项删除。
在开始编写这个《待办事项列表》应用前,我们先来学习一下Svelte的基本语法。
假设,我不是一个做事有条理的人,需要建立一个待办事项程序,并希望这个待办事项程序能帮助逐一完成所有的事情。
所有大家和我一起,踏上这个Svelte开发之旅,让我们一起构建这个应用程序。
先决条件:
这是您开始学习Svelte所需的内容:
!!!小提示:git bash终端中,有时候不能正常使用vite脚手架键入文字。(右键git bash here打开的终端)
可以通过增加一下内容,使得vite脚手架正常使用。
1 2 nano ~/.bashrc export MSYS="enable_pcon"
创建第一个svelte程序:
目录结构:
编写第一个程序:Hello world
结论 使用 Svelte 后,我明白了为什么开发人员喜欢它。这是一个有前途的编译器(或框架),虽然不是每个项目都完美,但可以帮助你快速和交互式地构建一些东西。 它比其他工具更不复杂,使您能够在几分钟内开始运行。此外,如果您遇到障碍,您将在互联网上找到大量资源来指导您,并且社区对初学者很友好。 如果你想学习一个新的框架,或者想尝试一些不同的东西,Svelte绝对值得仔细研究。 你已经用过Svelte了吗?请告诉我你对它的看法。
2、svelte基本语法 1、数据渲染
将变量放进一对花括号内,即可进行渲染,花括号内可以放表达式,即:
甚至还可以对标签的属性进行简写,例如对img标签src属性进行简写:
2、双向绑定 双向绑定只需要通过 bind:value 即可完成。若单选框组、复选框组:还需要添加bind:group属性和value值。
1 2 3 4 5 6 <script> let name = 'world'; </script> <input bind:value={name}> <h1>Hello {name}!</h1>
checkbox双向绑定:
1 2 3 4 5 6 7 <script> let yes = false; </script> <label> <input type="checkbox" checked={yes}> </label>
复选框组:
1 2 3 <input type=checkbox bind:group={books} name="books" value={‘钢铁‘}> <input type=checkbox bind:group={books} name="books" value={‘卖火柴‘}> <input type=checkbox bind:group={books} name="books" value={‘唐诗300首‘}>
单选组:
1 2 3 <input type=radio bind:group={books} name="books" value={‘钢铁‘}> <input type=radio bind:group={books} name="books" value={‘卖火柴‘}> <input type=radio bind:group={books} name="books" value={‘唐诗300首‘}>
select:
1 2 3 4 5 6 7 <select value={selected} on:change="{() => answer = ''}"> {#each questions as question} <option value={question}> {question.text} </option> {/each} </select>
3、样式渲染 行内样式:
1 2 3 4 <p style:color=‘red’ style:--opacity="{bgOpacity}" >this is text</p>
样式表:
按条件应用类名:
1 <button class :selected="{current === 'foo'}" >clickme</button>
简写:
1 2 3 <div class:big > big类名 </div >
使得项目支持scss语法。
想要使得项目支持scss,样式预处理语言。
需要先安装预处理器:svelte-preprocess, 由于需要支持scss,那sass当然也需要进行安装。
npm install svelte-preprocess node-sass --save-dev
安装好预处理器后,还需要对脚手架配置文件vite.config.js进行修改:
最终修改如下:
1 2 3 4 5 6 7 8 9 10 11 12 import { defineConfig } from "vite" ;import { svelte } from "@sveltejs/vite-plugin-svelte" ;import sveltePreprocess from "svelte-preprocess" ;export default defineConfig ({ plugins : [ svelte ({ preprocess : sveltePreprocess (), }), ], });
将scss写在style即可。不要忘记,将lang和type属性写上。
1 2 3 4 5 6 7 8 9 10 11 12 13 <div class="bluetext"> 蓝色字符串, <span class="violettext">紫色字符串</span> </div> <style lang="scss" type="text/scss"> .bluetext { color: blue; .violettext { color: violet; } } </style>
4、创建组件 在svelte项目中,每一个svelte为后缀的文件都是一个组件。
导入组件的方式也十分方便,使用import进行导入即可。千万不要忘记加svelte文件后缀。
4.1、匿名插槽 父组件:
1 2 3 4 5 6 7 8 <script> import Box from './Box.svelte' ; </script> <Box > <h2 > Hello!</h2 > <p > This is a box. It can contain anything.</p > </Box >
子组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <div class ="box" > <slot > </slot > </div> <style > .box { width : 300px ; border : 1px solid #aaa ; border-radius : 2px ; box-shadow : 2px 2px 8px rgba (0 ,0 ,0 ,0.1 ); padding : 1em ; margin : 0 0 1em 0 ; } </style >
4.2、具名插槽 父组件:
1 2 3 4 5 6 7 8 9 10 <ContactCard > <span slot ="name" > P. Sherman </span > <span slot ="address" > 42 Wallaby Way<br > Sydney </span > </ContactCard >
子组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <article class ="contact-card" > <h2 > <slot name ="name" > <span class ="missing" > Unknown name</span > </slot > </h2 > <div class ="address" > <slot name ="address" > <span class ="missing" > Unknown address</span > </slot > </div > <div class ="email" > <slot name ="email" > <span class ="missing" > Unknown email</span > </slot > </div > </article>
作用域插槽:
1 2 3 <Hoverable let :hovering={active}> {active} </Hoverable >
1 2 3 4 5 6 7 <script> let hovering; </script> <div on:mouseenter ={() => hovering = true} on:mouseleave={() => hovering = false}> <slot hovering ={hovering} > </slot > </div >
5、父传子 父传子的过程需要子组件暴露属性,父组件才能进行参数的传递。
如何暴露属性? 子组件可以在定义响应式变量的过程中,在前面加上export关键词,即可定义参数属性。
父组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script> import Child from "./Child.svelte"; </script> <div class="c-parent"> 我是父组件 <Child text="你好子组件" /> </div> <style lang="scss" type="text/scss"> .c-parent { width: 500px; height: 500px; background-color: rgb(29, 210, 255); } </style>
子组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script> export let text = ""; // 此处暴露出去的值,可以赋值默认值。 </script> <div class="c-child"> 我是子组件 <br /> 父组件信息:{text} </div> <style lang="scss" type="text/scss"> .c-child { width: 300px; height: 300px; background-color: rgb(166, 39, 245); } </style>
最终效果:
若子组件定义多个属性,父组件还可以通过解构的方式去传递参数:
子组件:
1 2 3 4 <script> export let name; export let age; </script>
父组件:
1 2 3 4 5 6 7 8 <script> let userinfo = { name: "小明", age: 18 } </script> <Child {...userinfo} />
6、子传父 在svelte中提供了一个创建事件调度器的方法createEventDispatcher来创建事件调度方法,开发者可以利用该事件调度方法来调度事件。从而达到子传父的目的。
父组件:在父组件中监听自定义方法on:hello,当子组件调度hello事件的时候,父组件能接收到传递过来的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script> import Child from "./Child.svelte"; </script> <div class="c-parent"> 我是父组件 <Child text="你好子组件" on:hello={(e) => { console.log("父组件收到的信息:", e.detail); }} /> </div> <style lang="scss" type="text/scss"> .c-parent { width: 500px; height: 500px; background-color: rgb(29, 210, 255); } </style>
子组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <script> import { createEventDispatcher } from "svelte"; const dispatch = createEventDispatcher(); const sendToParent = () => { dispatch("hello", "this is message"); }; export let text = ""; </script> <div class="c-child"> 我是子组件 <br /> 父组件信息:{text} <br /> <button on:click={sendToParent}>传递到父组件</button> </div> <style lang="scss" type="text/scss"> .c-child { width: 300px; height: 300px; background-color: rgb(166, 39, 245); } </style>
上下文传参:
定义:
1 2 3 4 5 6 7 <script> import { setContext } from 'svelte' ; setContext ('mykey' , { a : "aaaaaaaaaaaaaa" , b : "bbbbbbbbbbbbbb" }); </script>
使用:
1 2 3 4 <script> import { getContext } from 'svelte' ; const { a, b } = getContext ('mykey' ); </script>
7、关于渲染html字符串 在svelte中提供一个特殊的标记 @html,使用该标记可以为我们渲染html字符串。
8、svelte事件 在svelte中定义事件也十分简单,与原生类似,不同的是,需要在on后面加上冒号。
格式如:on:事件名={方法引用}
修饰符:
preventDefault
— 停止默认事件修饰符
stopPropagation
—停止冒泡修饰符
passive
— 提高滚动性能
nonpassive
— 显式的设置passive: false
capture
—捕获阶段处理事件
once
— 只执行一次,完了后移除事件,使得下次不能被执行。
self
— 仅在事件对象event.target为元素本身时执行事件。
trusted
— 只有 event.isTrusted
是 true
才进行触发。
例子:
1 <button on:click|once={事件函数}>点击我</button>
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <script> let count = 0 ; const reduce = ( ) => { count--; }; const add = ( ) => { count++; }; </script> <div > 数量: <button on:click ={reduce} > -</button > {count} <button on:click ={add} > +</button > </div >
效果如下:
9、svelte中的反应性 从第一小节可得知,开发者只需要定义一个变量,则该变量就是响应式。
在svelte中,提供一个反应性的语法,在script标签中用$:符合进行定义。先来理解什么是反应性,当被依赖的响应式变量发生改变的时候,会自动同步更新反应性语法里面的表达式。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script> let count = 0; const reduce = () => { count--; }; const add = () => { count++; }; $: console.log("count变成:%d", count); </script> <div> 数量: <button on:click={reduce}>-</button> {count} <button on:click={add}>+</button> </div>
效果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <script> let count = 0; const reduce = () => { count--; }; const add = () => { count++; }; let price = 16.8; $: console.log("count变成:%d", count); $: total = (count * price).toFixed(2); </script> <div> 数量: <button on:click={reduce}>-</button> {count} <button on:click={add}>+</button> <br /> 价格:{price} 合计:{total} </div>
效果如下:
10、修改数组或对象 在开发过程中经常会遇到一个问题,就是虽然修改了数组,但是不会产生效果的情况。
为什么会产生这样的问题呢?原因是由于数组和对象变量的指向地址并无发生变化,使得sevelte不能识别是否发生的变量,无法进一步的触发渲染事件。
如何解决该问题?可以通过浅拷贝或深拷贝的形式,使得变量所指向的地址发生改变即可。
通常做法有:
对象:
1、Object.assign({}, obj1, obj2)
2、{…obj1, …obj2}
3、JSON.parse(JSON.stringify(obj1))
数组:
1、[…arr1, …arr2]
2、JSON.parse(JSON.stringify(arr1))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script> let arr = [1, 2, 3]; $: total = arr.reduce((total, val) => (total += val)); </script> <div> {arr.join(" + ")} = {total} <br /> <button on:click={() => { arr.push(arr.length + 1); arr = [...arr]; }}>add item</button > </div>
11、条件渲染 svelte有着自己的一套模板语法,使用起来结构更加清晰.
可以看到如下代码,条件渲染的条件是放在标签语法{#if}里面,而分支用 {:else} 分开,最终再以{/if}结束。
1 2 3 4 5 6 7 8 9 <script> let flag = true; </script> {#if flag} <div>真的</div> {:else} <div>假的</div> {/if}
结果:真的
当然,条件渲染也支持嵌套。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \<script\> let flag = true; let flag2 = false; \<\/script\> {#if flag} <div>真的</div> {#if flag2} <div>真的</div> {:else} <div>假的</div> {/if} {:else} <div>假的</div> {/if}
结果:真的
假的
12、列表渲染 同样svelte有对于循环也是有响应的模板语法。
格式:
1 2 3 {#each 数组 as 数组项目, 数组下标 (唯一的键值)} <div>{数组项目.属性}</div> {/each}
示例1、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script> import { each } from "svelte/internal"; let arr = [ { name: "小明", age: 20 }, { name: "小红", age: 19 }, { name: "小蓝", age: 20 }, { name: "小天", age: 15 }, ]; </script> {#each arr as item, index} <div> {index}、姓名:{item.name} 年龄:{item.age} </div> {/each}
示例2: 亦可以通过each后面的圆括号来指定唯一的键(key)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script> import { each } from "svelte/internal"; let arr = [ { id: 1, name: "小明", age: 20 }, { id: 2, name: "小红", age: 19 }, { id: 3, name: "小蓝", age: 20 }, { id: 4, name: "小天", age: 15 }, ]; </script> {#each arr as item, index (item.id)} <div> {index}、姓名:{item.name} 年龄:{item.age} </div> {/each}
10、Await模板标签
svelte有个与promise配合使用的模板标签,以提高用户的体验感。
语法1:含等待、成功、失败状态(较为常用)
1 2 3 4 5 {#await Promise} 等待状态 {:then 成功值} 成功状态 {/await}
语法2:不含失败和等待状态
1 2 3 {#await Promise then 成功值} 成功状态 {/await}
例子1、
1 2 3 4 5 6 7 8 9 10 11 12 13 <script> let timer = new Promise((resolve) => { setTimeout(() => { resolve("倒计时完成"); }, 3000); }); </script> {#await timer} loading... {:then r} {r} {/await}
例子2、
1 2 3 4 5 6 7 8 9 10 11 <script> let timer = new Promise((resolve) => { setTimeout(() => { resolve("倒计时完成"); }, 3000); }); </script> {#await timer then r} {r} {/await}
13、绑定元素 可以通过bind:this,将元素绑定到具体的变量中去。
1 2 3 4 5 6 7 8 9 <script> let input; export function focus() { input.focus(); } </script> <input bind:this={input} />
3、Svelte基础语法 1、生命周期 什么是生命周期?生命周期就像人的生老病死一样是具体的某个时间段。那么软件也是一样,有特定的具体时刻所触发的事件。
svelte中的生命周期:onMount、onDestroy、beforeUpdate、afterUpdate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <script> import { onMount, onDestroy, beforeUpdate, afterUpdate } from 'svelte'; // 挂载期 onMount(async () => { // 一般可以通过挂载来进行网络请求。 }); // dom节点更新前 beforeUpdate(() => { // 用于记录dom节点更新前的状态 }) // dom节点更新后 afterUpdate(() => { // 在dom接口更新后所需事件 }) // 卸载期 onDestroy(() => { // 卸载工作 // 例如释放变量、删除时钟。 }); </script>
2、tick的用法 tick函数返回一个Promise, 你可以在任意地方使用tick。它的作用是:有了await tick()后,它不会里面刷新dom,而去等待下一次微任务就绪的时候(包括其他组件已经渲染完成)再继续往下执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <script> import { tick } from "svelte"; let count = 0; async function hello() { count++; new Promise((resolve) => { setTimeout(() => { resolve("hello"); }, 3000); }).then((res) => { console.log(res); }); await tick(); console.log(count); } </script> count: {count} <button on:click={hello}>click me</button>
3、全局状态管理 store.svelte文件:
1 2 import { writable } from 'svelte/store' ;export const count = writable (0 );
App.svelte
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <script> import { count } from './stores.js'; // 减少 function decrement() { count.update(n => n - 1); } // 增加 function increment() { count.update(n => n + 1); } // 重置 function reset() { count.set(0); } let countValue; count.subscribe(value => { countValue = value; }); </script> <button on:click={increment}>+</button> {countValue} 简写:{$count} <button on:click={decrement}>-</button> <br /> <button on:click={reset}>重置</button>
只读全局仓库:只允许内部修改
1 2 3 4 5 6 7 8 9 export const time = readable (new Date (), function start (set ) { const interval = setInterval (() => { set (new Date ()); }, 1000 ); return function stop ( ) { clearInterval (interval); }; });
利用derived基于原有的仓库数据进行定义新变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { readable, derived } from 'svelte/store' ;export const time = readable (new Date (), function start (set ) { const interval = setInterval (() => { set (new Date ()); }, 1000 ); return function stop ( ) { clearInterval (interval); }; }); const start = new Date ();export const elapsed = derived ( time, $time => Math .round (($time - start) / 1000 ) );
4、tweened补间动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script> import { tweened } from 'svelte/motion' ; import { cubicOut } from 'svelte/easing' ; const progress = tweened (0 , { duration : 400 , easing : cubicOut }); </script> <progress value ={$progress} > </progress > <button on:click ="{() => progress.set(0)}" > 0%</button > <button on:click ="{() => progress.set(0.5)}" > 50%</button > <button on:click ="{() => progress.set(1)}" > 100%</button > <style > progress { display : block; width : 100% ; } </style >
5、spring动画 spring是用于替代tweened适用于实时性更高的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <script> import { spring } from 'svelte/motion' ; let coords = spring ({ x : 50 , y : 50 }, { stiffness : 0.1 , damping : 0.25 }); let size = spring (10 ); </script> <div style="position: absolute; right: 1em;"> <label> <h3>stiffness ({coords.stiffness})</h3> <input bind:value={coords.stiffness} type="range" min="0" max="1" step="0.01"> </label> <label> <h3>damping ({coords.damping})</h3> <input bind:value={coords.damping} type="range" min="0" max="1" step="0.01"> </label> </div> <svg on:mousemove="{e => coords.set({ x: e.clientX, y: e.clientY })}" on:mousedown="{() => size.set(30)}" on:mouseup="{() => size.set(10)}" > <circle cx={$coords.x} cy={$coords.y} r={$size}/> </svg> <style> svg { width: 100%; height: 100%; } circle { fill: #ff3e00; } </style>
6、显隐动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <script> import { fade, fly } from 'svelte/transition' ; let visible = true ; </script> <label > <input type ="checkbox" bind:checked ={visible} > visible </label > {#if visible} <p transition:fade > Fades in and out </p > <p transition:fly ="{{ y: 200, duration: 2000 }}" > Flies in and out </p > <p in:fly ="{{ y: 200, duration: 2000 }}" out:fade > Flies in, fades out </p > {/if}
7、其他 window对象
1 <svelte:window on:keydown={handleKeydown}/>
body对象
1 2 3 4 <svelte:body on:mouseenter ={handleMouseenter} on:mouseleave ={handleMouseleave} />
Svelte项目实战 1、Axios封装 安装axios
npm install axios
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 export function fetch (uri, data, method = "POST" , responseType = "json" ) { return new Promise ((resolve, reject ) => { axios ({ url : BASEURL + uri, method : method, params : method === "GET" ? data : null , data : method === "POST" ? data : null , responseType : responseType, }) .then (function (response ) { resolve (response.data ); }) .catch (err => { reject (err); }); }); }
2、数据请求 创建api.js文件,导入fetch文件。
在api.js写请求接口。
3、页面制作 使用蓝湖还原设计图。
4、路由配置 安装路由依赖:
1 npm install svelte-spa-router
定义路由:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import Home from './routes/Home.svelte' import Author from './routes/Author.svelte' import Book from './routes/Book.svelte' import NotFound from './routes/NotFound.svelte' const routes = { '/' : Home , '/author/:first/:last?' : Author , '/book/*' : Book , '*' : NotFound , }
使用路由:
1 2 3 <body > <Router {routes }/> </body >
接收路由参数:
1 2 3 4 5 <script> import {location, querystring} from 'svelte-spa-router' </script> <p > The current page is: {$location}</p > <p > The querystring is: {$querystring}</p >
路由跳转:
声明式:
1 2 3 4 5 <script > import {link} from 'svelte-spa-router' let myLink = "/book/456" </script > <a use:link ={myLink} > The Biggest Princess</a >
导航式:
1 2 3 4 5 6 7 8 9 10 11 import {push, pop, replace} from 'svelte-spa-router' push ('/book/42' )pop ()replace ('/book/3' )