svelte归档

本文最后更新于:2022年4月13日 下午

rollup作者搞的框架,玩玩看orz..

学了一两天,跟vue比较像的一点是都是用模板语法,结构啥的都比较像,毕竟框架要解决的问题都是相似的。但跟vue的实现是完全不同,这部分看情况吧,有需要就去研究下。

1.模版里使用变量

1
2
3
4
5
6
<p>{name}</p>
<img src={url}></img>
<script>
let name = 'john';
let url = 'xxx/xxx.jpg';
</script>

更新数组与对象

  • 数组

    并不支持数组的原生方法(push,pop,shift,unshift,splice),也就是说以上方法不会触发响应。

  • 对象

    经验法则:变量名必须出现在赋值语句左侧,否则不触发响应(如变量名obj)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    let obj = {
    foo:{
    bar: 'aaa',
    }
    }
    // 触发响应
    obj = { foo: {bar: 'bbb' } };
    obj.foo = { bar: 'bbb' };
    obj.foo.bar = 'bbb';

    // 不触发响应
    let foo = obj.foo;
    foo = { bar: 'ccc' };
    foo.bar = 'ccc';

2.反应式(响应)

  • 反应式声明(类似vue的computed)

    1
    2
    3
    4
    <script>
    let count = 0;
    $: double = count * 2;
    </script>
  • 运行时使用

    1
    2
    3
    4
    5
    6
    7
    8
    let count = 0;
    // 单行
    $: console.log(`the count is ${count}`);
    // 代码块
    $: {
    console.log(`the count is ${count}`);
    alert(`the count is ${count}`)
    }

3.循环

1
2
3
4
5
6
7
8
9
10
11
12
<script>
let cats = [
{id: 0, name: 'Mimi'},
{id: 1, name: 'Miao'},
{id: 2, name: 'Tom'},
]
</script>
<ul>
{#each cats as cat}
<li>id:{cat.id}, name:{cat.name} </li>
{/each}
</ul>

默认第二个参数是数组的index

1
2
3
{#each cats as cat, index}
<li>index:{index}, name:{cat.name}</li>
{/each}

当然也可以进行结构赋值

1
2
3
{#each cats as {id, name}, index}
<li>index: {index}, id:{id}, name:{name}</li>
{/each}

唯一标识符,也就是key值。

1
2
3
{#each cats as cat(cat.id)}
<li> name:{cat.name}</li>
{/each}

svelte内部是用Map来处理key,因此你完全可以把整个对象作为key

1
2
3
{#each cats as cat(cat)}
<li> name:{cat.name}</li>
{/each}

4.事件

可以用on:<event>的形式监听任何事件(注意冒号:后不能加空格)

1
2
3
4
5
6
<script>
function handleClick(){
console.log('click');
}
</script>
<div on:click={handleClick}></div>

修饰符列表

once

仅执行一次

1
2
3
4
5
6
<script>
function handleClick(){
console.log('click');
}
</script>
<div on:click|once={handleClick}></div>

capture

在capture阶段触发而不是bubbling阶段

self

仅当event.target是自身时才执行

更多….

上述修饰符也可以组合使用,如 on:click|once|capture={handleClick}

5.组件事件

有点像vue的emit和on

例如,约定事件message,子组件Inner.svelte

1
2
3
4
5
6
7
8
9
10
11
12
<script>
import {createEventDispatcher} from 'svelte';
const dispatch = createEventDispatcher();
function handleClick(){
dispatch('message', {
text: 'hello',
})
}
</script>
<button on:click={handleClick}>
Button
</button>

父组件app.svelte,在事件的detail属性里得到传参

1
2
3
4
5
6
7
8
9
10
<script>
import Inner from './Inner.svelte';
function handleMessage(event) {
console.log(event.detail); // {text: "hello"}
}
</script>

<main>
<Inner on:message={handleMessage} />
</main>

注意:exclamation::​组件事件不会冒泡,如果Inner和app组件中间还有一层组件middle,那么需要在middle组件处转发事件,才能使Inner的触发的事件传递到app上

1
2
3
4
5
// middle组件内
function forward(event){
dispatch('message', event.detail);
}
<Inner on:message={forward}/>

有点麻烦,简写的形式是不给message事件传值,不传值的情况默认转发所有事件

1
2
3
4
<script>
import Inner from './Inner.svelte'
</script>
<Inner on:message/>

6.双向绑定

使用bind:的形式,input输入会修改变量name,改变属性name也会修改input里的值

1
2
3
4
5
6
7
8
9
<script>
let name = '';
function handleInput(){
console.log(name);
}
</script>

<input bind:value={name} on:input={handleInput}>
<h1>Hello {name}!</h1>

定义input的值类型, number, range, checkbox, radio

1
2
3
4
5
6
7
<script>
let a = 0;
</script>
<label>
<input type=number bind:value={a} min=0 max=10>
<input type=range bind:value={a} min=0 max=10>
</label>

7.生命周期

  • onMounted(),如果回调函数的返回值为函数,那么将在销毁组件时执行

  • onDestroy()

  • beforeUpdate() / afterUpdate()

  • tick(),返回一个promise,在dom更新后执行。类似于vue里的nextTick()

8.Store

基本使用

store.js

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
<script>
import { count } from './stores.js';
function increment() {
count.update(n=>n+1);
}
function decrementer(){
count.update(n=>n+1);
}
function resetter(){
count.set(0);
}
</script>
<button on:click={increment}>+</button>
<button on:click={decrementer}>-</button>
<button on:click={resetter}>reset</button>

避免内存泄漏

使用unsubscribe

1
2
3
4
5
let count_value;
const unsubscribe = count.subscribe(value => {
count_value = value;
});
onDestroy(unsubscribe);

简写–自动subscribe,使用$来快速使用store的变量。仅在store变量在顶级作用域声明或import时生效。

1
2
3
4
5
6
<script>
import { count } from './stores.js';
</script>
<h1>
the count is {$count}
</h1>