Svelte入门基础简介

Posted 登楼痕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Svelte入门基础简介相关的知识,希望对你有一定的参考价值。

Svelte 是一种全新的构建用户界面的方法。传统框架如 React 和 Vue 在浏览器中需要做大量的工作,而 Svelte 将这些工作放到构建应用程序的编译阶段来处理。

Svelte在语法上非常简单,和vue很像,但是api会简单很多,因此代码量会少很多,并且没有虚拟DOM,所以代码体积会小很多,也没有很复杂的状态管理。

一、基本用法 (1)一个.svelte就是一个组件,有html,css和js代码封装组成。类似vue的写法,<script></script>中定义的变量,可以使用单大花括号写在html中,例如:
<script>     let src = 'tutorial/image.gif';     let name = 'Rick Astley'; </script> <img src alt="name dances.">
当属性名和变量名是一样的时候。我们可以简写省略掉变量名。 (2)样式:对于css样式,就行写html文件那样去写:
<style>     p         color: purple;         font-family: 'Comic Sans MS', cursive;         font-size: 2em;      </style> <p>This is a paragraph.</p>
重要的第一点是,这个样式的作用域限定于当前组件中。不会对其他地方的p标签产生影响。 (3)组件嵌套:上面说的例子都是简单的一个小组件,然而完整的应用程序是由多个组件构成的,使用组件也很简单,import进来就可以使用,并且为了区分自定义组件和普通HTML标签,组件名必须首字母大写:
<p>This is a paragraph.</p> <Nested/> <script> import Nested from "./Nested.svelte"; </script>
(4)字符串转为HTML标签:类似于vue里的v-html和react里的dangerouslySetInnerHTML。Svelte里面用@html ......的形式,这种情况下,需要手动转义非信任源的HTML标签来避免XSS攻击。
<script>     let string = `this string contains some <strong>HTML!!!</strong>`; </script> <p>@html string</p>
二、响应式 (1)赋值:响应式也是Svelte的核心之一,在js里直接修改绑定的变量,就可以同步看到DOM上数据发生改变,很简单:
<script>     let count = 0;     function handleClick()         count++;      </script> <button on:click=handleClick>     Clicked count count === 1 ? 'time' : 'times' </button>
(2)声明:类似vue里的computed,这里叫“反应式声明”,这样写: let count = 0; $: doubled = count * 2; 然后就可以在html里像用count那样使用doubled。 以此类推,$: 后面也可以跟一串逻辑,比如:
$:         console.log(`the count is $count`);         alert(`I SAID THE COUNT IS $count`);
甚至是逻辑表达式:
$: if (count >= 10)         alert(`count is dangerously high!`);         count = 9;
(3)更新数组和对象:Svelet的响应式是有赋值语句触发的,所以像数组的push、splice这些操作就不会触发更新,所以做法是需要手动添加一个看似多余的赋值语句:
<script>     let numbers = [1, 2, 3, 4];     function addNumber()         numbers.push(numbers.length + 1);         numbers = numbers;         // 或者写成         // numbers = [...numbers, numbers.length + 1];          $: sum = numbers.reduce((t, n) => t + n, 0); </script> <p>numbers.join(' + ') = sum</p> <button on:click=addNumber>     Add a number </button>
对于数组和对象的属性赋值,就是正常的obj.foo=1或者arr[i]=x那样来。 三、属性 组件之间的传值很简单,父组件依旧写成正常的传值:
<Nested answer=42/>
在子组件里,需要将answer变量export出去:
<script>     export let answer; </script> <p>The answer is answer</p>
当然,也可以在后面赋初始值:
export let answer = "hello";
属性传递也支持结构运算符,比如想把一个对象的属性值分别传递到子组件,不用写一大排,只用
<script>     import Info from './Info.svelte';     const pkg =         name: 'svelte',         version: 3,         speed: 'blazing',         website: 'https://svelte.dev'     ; </script> <Info ...pkg/>
在子组件里,分别export let name; export let version;这些就行了。 四、逻辑 (1)条件逻辑: 在HTML里面加上逻辑标记,#if xxxxx,单个if的例子:
#if user.loggedIn         <button on:click=toggle>                 Log out         </button> /if #if !user.loggedIn         <button on:click=toggle>                 Log in         </button> /if
对于if-else的写法:
#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
这里面,#表示一个块逻辑的开始,/表示结束,:表示继续。 (2)遍历:使用each。也可以写成each cats as id, name,然后直接使用id和name来代替cat.id和cat.name。
<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,index         <li><a target="_blank" href="https://www.youtube.com/watch?v=cat.id">             index+1 cat.name         </a></li>     /each </ul>
类似于vue里v-for的key,这里我们可以这样做,这里就是把id作为key:
#each things as thing (thing.id)         <Thing current=thing.color/> /each
(3)await:Svelte可以直接把promise的逻辑写在标签里,在标签中执行promise并展示回调结果:
<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 then number <p>number</p> /await // 或者可以写的更详细 #await promise         <p>...waiting</p> :then number         <p>The number is number</p> :catch error         <p style="color: red">error.message</p> /await
五、事件 (1)事件监听:使用on: 指令监听,on:click,on:mousemove这些:
<script>     let m = x: 0, y: 0 ;     function handleMousemove(event)         m.x = event.clientX;         m.y = event.clientY;      </script> <style>     div width: 100%; height: 100%; </style> <div on:mousemove=handleMousemove>     The mouse position is m.x x m.y </div>
当然,handleMousemove可以替换为箭头函数写成行内的形式:
<div on:mousemove="e => m = x: e.clientX, y: e.clientY ">    The mouse position is m.x x m.y </div>
事件监听的时候也可以使用事件修饰符,用‘|’分隔,可以连续使用多个: on:click|once|capture=handleEvent 可用的事件修饰符有:preventDefault、stopPropagation、passive、capture、once、self。 (2)组件通信:子组件通过dispatch方法给父组件发消息
<script>   import createEventDispatcher from "svelte";   const dispatch = createEventDispatcher();     function sayHello()         dispatch('message',             text: 'Hello!'         );      </script> <button on:click=sayHello>     Click to say hellos </button>
在父组件中通过on监听:
<Inner on:message=handleMessage/>
上面提到的只是父子组件的事件传递,犹豫组件不会冒泡,对于深层嵌套的组件上的事件监听,就需要在中间的组件继续转发事件,但每次写一遍dispatch也比较臃肿,所以对于纯转发的行为,可以简写为:
<MiddleComponent on:message/>
在没有赋予特定值的情况下,意味着转发所有message事件。 特别的一点是,如果子组件内部想要接受父组件的点击事件,只需要在内部加上on:click: 父组件:
<script>     import FancyButton from './CustomButton.svelte';     function handleClick()         alert('clicked');      </script> <FancyButton on:click=handleClick/>
子组件:
<button on:click>     Click me </button>
六、绑定 (1)Svelte里的数据绑定,例如input标签,使用bind:value进行绑定:
<script>     let name = 'world'; </script> <input bind:value=name> <h1>Hello name!</h1>
如果绑定的值与变量同名,比如bind:value=value这种,可以省略写为bind:value。 当然不仅是input.value可以,像复选框的checked也是类似:
 <input type=checkbox bind:checked=yes>
上述是单个值的绑定,那么绑定更多值的时候,可以用bind:group将value放在一起,在bind:group里面同一组的单选框互斥,复选框则会形成数组。
<label>    <input type=checkbox bind:group=flavours value=flavour> </label>
(2)bind:this可以绑定任何标签或者组件,并且可以获得标签的引用:
<canvas     bind:this=canvas     width=32     height=32 ></canvas> ..... // 这样在onMount生命周期里就可以获得canvas的Dom onMount(() =>   const ctx = canvas.getContext('2d');   .....
(3)组件的属性也可以绑定,比如在父组件引用子组件处写上:
<Keypad bind:value=pin on:submit=handleSubmit/>
那么在子组件中修改value的时候,pin就会立即获得同步更新。不过这个功能不要滥用,因为不好掌握数据流向。 七、生命周期 onMount,onDestroy,beforeUpdate和afterUpdate没啥好说的,tick这个和Vue的nextTick类似。

 

以上是关于Svelte入门基础简介的主要内容,如果未能解决你的问题,请参考以下文章

Svelte入门基础简介

Svelte 内部结构:反应式声明语法如何工作

Svelte 反应性如何在函数内部工作?

Svelte:双向绑定触发反应性两次

如何在 Svelte 的类属性中使用反应函数?

Svelte 极简入门