Svelte基础
1. 基本使用
跟着官网demo学习Svelte随记 在Svelte后缀文件中编写代码:类似vue文件template、script、style三个代码块,svelte也有对应的代码块
<!-- {} 花括号对应vue中的'Mustache 语法' -->
<h1>Hello {name.toUpperCase()}!</h1>
<img {src} alt="{propValue}" />
<!-- 类v-html功能 -->
<p>{@html string}</p>
<!-- 组件使用 -->
<Nested />
<!-- 事件绑定 -->
<button on:click={increment}>
Clicked {count}
{count === 1 ? 'time' : 'times'}
</button>
<script>
//引入组件(组件使用
import Nested from './Nested.svelte';
let name = 'Svelte';
let src = '/xxxx.jpg';
let propValue = 'some value';
//类v-html功能
let string = `this string contains some <strong>HTML!!!</strong>`;
//事件绑定
let count = 0;
function increment() {
count += 1;
}
//计算属性声明
$: doubled = count * 2;
</script>
<style>
</style>
push、pop、shift、unshift、splice方法不会造成响应式视图的更新, 解决方法:
function addNumber() {
numbers = [...numbers, numbers.length + 1];
}
//这样更新响应式变量无效
// 准则:需要更新的响应式变量名 必须出现在赋值运算符的左边
function addNumber() {
let foo = obj.foo;
foo.bar=4;
}
//正确方法
obj.foo.bar = 4;
组件props定义与默认值方式
<script>
export let propName = '默认值';
export let another;
</script>
<p> propName is {propName} </p>
<p> another is {another} </p>
在app引入组件Component
<script>
import Comp from './Component.svelte'
const obj = {
propName: 'aa'
another: 'ss'
}
</script>
<Comp {...obj}/>
类v-if语句: # 是语句开始 ‘/’是语句结束 ‘:’是继续语句
{#if count>5}
<p>{count} is {count}</p>
{:else if count < 5}
<p>{count} is less than 5</p>
{:else}
<p>{count}</p>
{/if}
for循环,括号赋值key
{#each colors as color,i (color.id)}
<button
aria-current={selected === color}
aria-label="{color}"
style="background: {color}"
on:click={() => selected = color}
>{i}</button>
{/each}
await语法
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
<!-- 简写 -->
{#await promise then number}
<p>The number is {number}</p>
{/await}
事件监听
<script>
let m = { x: 0, y: 0 };
function handleMove(event) {
m.x = event.clientX;
m.y = event.clientY;
}
</script>
<!-- 第一种写法 -->
<div on:pointermove={handleMove}>
The pointer is at {m.x} x {m.y}
</div>
<!-- 第二种写法 -->
<!-- <div on:pointermove={(e)=>{
handleMove(e)
}}>
The pointer is at {m.x} x {m.y}
</div> -->
<div on:pointermove={(e)=>{
m.x=e.clientX;
m.y=e.clientY;
}}>
The pointer is at {m.x} x {m.y}
</div>
<style>
div {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 1rem;
}
</style>
事件监听修饰符
<button on:click|once={() => alert('clicked')}>
Click me
</button>
组件自定义事件,要引入createEventDispatcher包并创建实例
<script>
import Inner from './Inner.svelte';
function handleMessage(event,msg) {
console.log(event,event.detail.text);
}
</script>
<Inner on:message={(e,msg)=>{
handleMessage(e,msg)
}}/>
<script>
import {createEventDispatcher} from "svelte"
const dispatch = createEventDispatcher();
function sayHello() {
dispatch('message', {
text: 'Hello!'
});
}
</script>
<button on:click={sayHello}>
Click to say hello
</button>
svelte组件事件触发默认不会向上冒泡,需要在中间组件添加
<script>
import {Inner} from 'Inner.svelte'
</script>
<Inner on:message/>
组件内绑定事件
<BigRedButton on:click={handleClick} />
//BigRedButton.svelte
<button on:click>
Push
</button>
双向绑定
<script>
let name = 'world';
</script>
<input bind:value={name} />
<h1>Hello {name}!</h1>
绑定input,radio和checkbox组group,将radio的value 和checkbox值赋值到变量和数组
<script>
let scoops = 1;
let flavours = [];
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
</script>
<h2>Size</h2>
{#each [1, 2, 3] as number}
<label>
<input
type="radio"
name="scoops"
value={number}
bind:group={scoops}
/>
{number} {number === 1 ? 'scoop' : 'scoops'}
</label>
{/each}
<h2>Flavours</h2>
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
<label>
<input
type="checkbox"
name="flavours"
value={flavour}
bind:group={flavours}
/>
{flavour}
</label>
{/each}
{#if flavours.length === 0}
<p>Please select at least one flavour</p>
{:else if flavours.length > scoops}
<p>Can't order more flavours than scoops!</p>
{:else}
<p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
of {formatter.format(flavours)}
</p>
{/if}
获取元素即vue中的ref
<script>
let div
</script>
<div class="chat" bind:this={div}>
dom的更新是在微任务中,可以等待tick后即dom更新后再做对应的操作
await tick();
2. 状态管理store
//store.svelte
<script>
import { writable } from 'svelte/store';
export const count = writable(0);
</script>
//App.svelte
<script>
import { count } from './stores.js';
import Incrementer from './Incrementer.svelte';//更新
let count_value;
count.subscribe((value) => { //赋值
count_value = value;
});
</script>
//Incrementer.svelte
<script>
import { count } from './stores.js';
function increment() {
count.update((n) => n + 1);
}
</script>
自动订阅store变量与注销
<script>
import { count } from './stores.js';
</script>
<h1>The count is {$count}</h1>
store的只读变量与衍生变量
import { readable } 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)
);
自定义导出store变量的实例方法(要有subscribe方法)
import { writable } from 'svelte/store';
function createCount() {
const { subscribe, set, update } = writable(0);
return {
subscribe,
increment: () => update((n) => n + 1),
decrement: () => update((n) => n - 1),
reset: () => set(0)
};
}
export const count = createCount();
可以在使用的过程中使用“双向绑定”对store的值进行设置和读取
<input bind:value={$name} />