Sveltejs file address svelte.dev

The Chinese document address is www.sveltejs.cn/

start

Create an application, the document reference www.sveltejs.cn/blog/svelte…

npx degit sveltejs/template svelte-app
cd svelte-app
Copy the code

If the sveltejs template fails to be created, you can download it locally using Git

git clone https://github./comsveltejs/template.git
cd template
npm install
Copy the code

To use typescript, do the following

To use typescript, do the following
node scripts/setupTypeScript.js
Copy the code

Introduction to the

Add data

Declare a variable. Use curly braces to display the contents of the variable to the page.

<script lang="ts"> let name: string = 'world' setTimeout(() => { name = 'shibin' }, 2000) </script> <main> <h1>Hello {name}! </h1> </main>Copy the code

The HTML displayed on the page

<h1>Hello world!</h1>
Copy the code

Add the style

Add a

<script lang="ts"> let name: string = 'world' </script> <main> <h1>Hello {name}! </h1> <p> Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps. </p> </main> <style> main { text-align: center; padding: 1em; max-width: 240px; margin: 0 auto; } h1 { color: #ff3e00; text-transform: uppercase; font-size: 4em; font-weight: 100; } @media (min-width: 640px) { main { max-width: none; } } </style>Copy the code

Nested components

Import the component in

<script lang="ts">
	import Hello from './Hello.svelte'
</script>

<main>
	<Hello/>
</main>
Copy the code

HTML tags

Normally, strings are inserted as plain text, but if you want to insert HTML snippets, you can use {@html… } to realize

<p>{@html string}</p>
Copy the code

Creating an application

Svelte provides plug-ins for Rollup and Webpack that can be configured as needed

  • rollup-plugin-svelte
  • svelte-loader

Other plug-ins can also use the template downloaded above directly

Once the project is configured, the compiler converts each component into a regular JavaScript class, which you can then simply import and instantiate with New

import App from './App.svelte'

const app = new App({
	target: document.body,
	props: {
		name: 'world'}})export default app
Copy the code

The assignment

Reactivity

Svelte keeps the DOM in sync with the state of your application. You only need to change the data, and Svelte automatically updates the DOM

<script lang="ts">
	import Hello from './Hello.svelte'
	let count: number = 0
	const handleClick = () => {
		count += 1
	}
</script>
<button on:click={handleClick}>Clicked {count} times</button>
Copy the code

The statement

Svelte provides Reactive Declarations when part of a component needs to be computed by other parts (such as computed properties in Vue)

<script lang="ts">
    let count = 0
    $: doubled = count * 2
</script>
Copy the code

Using {count * 2} on a page also works, but it’s better to use this declaration when you need to refer to it more than once

statements

Statements can also be evaluated

The following code executes the statement when the count value changes

<script lang="ts">
    let count = 0
    $: console.log(`the count is ${count}`);
</script>
Copy the code

To combine a group of statements into a block of code

<script lang="ts">
    let count = 0
    $: {
	console.log(`the count is ${count}`)
	alert(`I SAID THE COUNT IS ${count}`)
    }
</script>
Copy the code

You can even put $: in front of the if block. The following code executes the if block when count>=10

<script lang="ts"> let count = 0 $: if (count >= 10) { alert(`count is dangerously high! `) count = 9 } </script>Copy the code

Update arrays and objects

Svelte data updates are triggered by assignment statements, so push, slice, POP, etc. using arrays do not trigger automatic updates.

The following code will not be updated

<script lang="ts"> let arr:number[] = [1,2,3] function addNumber(){arr.push(arr.length + 1)} </script> <main> {arr} <button on:click={addNumber}>addNumber</button> </main>Copy the code

The solution is to reassign

<script lang="ts"> import Hello from './ hello.svelte 'let arr:number[] = [1,2,3] function addNumber(){ arr.push(arr.length + 1) arr = arr } </script>Copy the code

There is a more conventional approach

function addNumber() {
	arr = [...arr, arr.length + 1]}Copy the code

Properties are assigned to arrays and objects in the same way that values themselves are assigned.

function addNumber() {
    arr[arr.length] = arr.length + 1
}
Copy the code

A simple rule of thumb is that the name of the variable being updated must appear on the left side of the assignment statement

const foo = obj.foo;
// Does not trigger a reference to obj.foo.bar
foo.bar = 'baz';

// A reference to obj.foo.bar is triggered
// obj.foo.bar = 'baz';
Copy the code

References to obj.foo.bar are not updated unless obj = obj is used.

Props

Props is used to pass data from a parent component to a child component

<Hello name="world"/>
Copy the code

The child component can retrieve data passed by the parent through the export keyword

<script lang="ts"> export let name: string </script> <h1>Hello {name}! </h1>Copy the code

Set the default value for props

export let name: string = 'Shibin'
Copy the code

If your component has an object property, you can use… Object deconstruction syntax passes data to child components

<Hello {. obj} / >
Copy the code

logic

Conditions apply colours to a drawing

if

{#if user.loggedIn}
	<button on:click={toggle}>
		Log out
	</button>{/if} {#if ! user.loggedIn}<button on:click={toggle}>
		Log in
	</button>
{/if}
Copy the code

else

{#if user.loggedIn}
	<button on:click={toggle}>
		Log out
	</button>
{:else}
	<button on:click={toggle}>
		Log in
	</button>
{/if}
Copy the code

else if

{#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}
Copy the code

The list of rendering

<script lang="ts">
	let arr: number[] = [1, 2, 3]
</script>

<main>
	<ul>
		{#each arr as number}
			<li>{number}</li>
		{/each}
	</ul>
</main>
Copy the code

You can also use index as the second parameter (key), something like this:

{#each arr as number, index}
    <li>{index} {number}</li>
{/each}
Copy the code

In general, when you change the value in the each block, it will add or remove items at the end and update any changes, which may not be what you want.

To do this, we specify a unique identifier for the each block as the key value:

{#each things as thing (thing.id)}
	<Thing current={thing.color}/>
{/each}
Copy the code

(Thing.id) tells Svelte what needs to be changed.

Await

Use await to process asynchronous data in the tag

{#await promise}
	<p>. waiting</p>
{:then number}
	<p>The number is {number}</p>
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}
Copy the code

You can also ignore the first block if you don’t want the program to do anything until the request completes.

{#await promise then value}
	<p>the value is {value}</p>
{/await}
Copy the code

The event

Using on: directive in an element can add any event to the element

<div on:mousemove={handleMousemove}>
	The mouse position is {m.x} x {m.y}
</div>
Copy the code

Inline event handlers can also be declared

<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}">
	The mouse position is {m.x} x {m.y}
</div>
Copy the code

Event modifier

In Svelte, DOM event handlers have additional modifiers

<button on:click|once={handleClick}>
	Click me
</button>
Copy the code

Event modifiers in Svelte are

  • PreventDefault calls event.preventDefault(), called before the handler runs, to prevent the browser’s default behavior
  • StopPropagation Call event.stopPropagation() to prevent events from bubblings
  • Passive optimizes scrolling for Touch /wheel events (Svelte automatically adds scroll bars where appropriate).
  • Capture triggers event handlers in the Capture phase instead of the Bubbling phase
  • Once Deletes the event handler after running it once
  • Self is executed only if the Event. target is itself

Combination: on: click | once | the capture = {… }

Component events

A component can send custom events to its parent

<script lang="ts"> import {createEventDispatcher} from 'svelte' export let name: string = 'wd'; const dispatch = createEventDispatcher() function sayHello(){ dispatch('message',{ text: 'hello' }) } </script> <h1>Hello {name}! </h1> <button on:click={sayHello}>Say hello</button>Copy the code

The parent component receives custom events

<script>
	function handleMessage(e) {
		alert(e.detail.text)
	}
</script>
<Hello on:message={handleMessage}/>
Copy the code

Note that component events do not bubble and will need to be forwarded if multiple layers of delivery are required (custom event layer by layer)

Event forwarding can also be applied to DOM events.

<button>
	Click me
</button>
Copy the code
<FancyButton on:click={handleClick}/>
Copy the code

The binding

Form the binding

<script lang="ts">
	let name: string = 'shibin'
</script>
<div>
	<input bind:value={name}>
	{name}
</div>
Copy the code

number

Svelte can bind input to value. When type is number or range, no conversion is required. The default value is number

<script>
	let a = 1;
	let b = 2;
</script>

<label>
	<input type=number value={a} min=0 max=10>
	<input type=range value={a} min=0 max=10>
</label>

<label>
	<input type=number value={b} min=0 max=10>
	<input type=range value={b} min=0 max=10>
</label>

<p>{a} + {b} = {a + b}</p>
Copy the code

Single and multiple

<script lang="ts">
  let yes: string = true
</script>
<input type=checkbox bind:checked={yes}>
{yes}
<label>
Copy the code

Multiple check boxes

<script lang="ts">
let menu = [
	'Cookies and cream',
	'Mint choc chip',
	'Raspberry ripple'
];
let flavours = ['Mint choc chip'];

</script>
<h2>Flavours</h2>

{#each menu as flavour}
	<label>
		<input type=checkbox bind:group={flavours} value={flavour}>
		{flavour}
	</label>
{/each}
Copy the code

Check the checkbox

<script lang="ts">
let scoops = 1
</script>

<label>
	<input type=radio bind:group={scoops} value={1}>
	One scoop
</label>

<label>
	<input type=radio bind:group={scoops} value={2}>
	Two scoops
</label>

<label>
	<input type=radio bind:group={scoops} value={3}>
	Three scoops
</label>
Copy the code

textarea

The same applies to bind:value

<textarea bind:value={value}></textarea>
Copy the code

The value is the same as the variable name, but we can also use the shorthand form

<textarea bind:value></textarea>
Copy the code

select

The same applies to bind:value

<select bind:value={selected} >

Copy the code

The selection box contains a property called multiple, which in this case will be set to an array rather than a single value (similar to vUE).

Contenteditable binding

A tag that supports the Contenteditable =”true” attribute, using the binding of textContent to the innerHTML attribute:

<div
	contenteditable="true"
	bind:innerHTML={html}
></div>
Copy the code

This binding

This can be bound to any tag (or component) and allows you to get a reference to the render tag

<script lang="ts"> import { onMount } from "svelte" let canvas onMount(() => { const ctx = canvas.getContext('2d') // })  </script> <canvas bind:this={canvas} width={32} height={32} />Copy the code

Component bindings

Just as you can bind properties of DOM elements, you can also bind properties of components. For example, we can bind the value attribute inside the

component, like a form tag:

<Keypad bind:value={pin} on:submit={handleSubmit}/>
Copy the code

The life cycle

Each component has a life cycle that begins when it is created and ends when it is destroyed

onMount

OnMount runs after first rendering into the DOM

<script lang="ts">
	import { onMount } from "svelte"
	let canvas
	onMount(() => {
		console.log(canvas)
	})
</script>
<canvas bind:this={canvas}></canvas>
Copy the code

onDestroy

OnDestroy is executed when the component is destroyed

<script lang="ts">
	import { onMount, onDestroy } from "svelte";
	let canvas;
	let timer;
	onMount(() => {
		console.log(canvas);
		timer = setInterval(() => {
			console.log(new Date());
		}, 2000);
	});
	onDestroy(() => {
		clearInterval(timer);
	});
</script>

<canvas bind:this={canvas} />
Copy the code

BeforeUpdate and afterUpdate

  • BeforeUpdate function implementation is executed before DOM rendering is complete
  • AfterUpdate is executed after rendering is complete

trick

In Svelte, whenever a component state changes, the DOM does not update immediately. Instead, it waits for the next MicroTask to see if there are any other changing states or components that need to be updated. This saves the browser from doing nothing and makes it more efficient.

import { tick } from 'svelte'; .// Wait for DOM updates
await tick();
// Dom updated operation
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd; .Copy the code

Store

Like vue and React,

// store/index.ts
import { writable } from 'svelte/store'

export const count = writable(0) 
Copy the code
/ / subscribe
const unsubscribe = count.subscribe(value= > {
	count_value = value;
})

function increment() {
	// Trigger the update
	count.update(n= > n + 1)}/ / reset
function reset() {
	count.set(0)}Copy the code

Here’s an example

<script lang="ts">
	import {count} from './store'
	import Hello from './Hello.svelte'
	let count_value
	const unsubscribe = count.subscribe(value => {
		count_value = value
	})
</script>
<h1>The count is {count_value}</h1>
<Hello/>
Copy the code
<script lang="ts"> import {count} from './store' export let name: string = 'wd'; let count_value; const unsubscribe = count.subscribe(value => { count_value = value; }); function increment() { count.update(n => n + 1); } function reset() { count.set(0); } </script> <h1>Hello {name}! </h1> {count_value} <button on:click={increment}>+</button> <button on:click={reset}>reset</button>Copy the code

Automatically subscribe

Subscribe is not automatically destroyed when the component is destroyed. You need to manually call unSUBSCRIBE to destroy it

import { onDestroy } from 'svelte';
import { count } from './stores.js';
import Incrementer from './Incrementer.svelte';
import Decrementer from './Decrementer.svelte';
import Resetter from './Resetter.svelte';

let count_value;

const unsubscribe = count.subscribe(value= > {
	count_value = value;
});

onDestroy(unsubscribe);
Copy the code

Above, when the component has a lot to destroy manually, you can use $to refer to values in the store

<script>
	import { count } from './stores.js';
	import Incrementer from './Incrementer.svelte';
	import Decrementer from './Decrementer.svelte';
	import Resetter from './Resetter.svelte';

	console.log('count:' +$count)
</script>

<h1>The count is {$count}</h1>
Copy the code

Custom store

As long as an object uses subscribe correctly, it is called a store

For example, the Count Store includes increment, Decrement, and Reset components in the previous example to prevent exposure to set and update methods

function createCount() {
	const { subscribe, set, update } = writable(0);

	return {
		subscribe,
		increment: () = > update(n= > n + 1),
		decrement: () = > update(n= > n - 1),
		reset: () = > set(0)}; }Copy the code

Binding store

<script lang="ts">
	import {count} from './store'
</script>
<input type="number" bind:value={$count}>
<Hello/>
Copy the code