svelte的一些基础demo

发布时间 2023-12-28 20:44:33作者: 欧阳码农

脚手架

Vite:vite是集成了svelte,初始化的时候选择svelte就行了。

npm init vite

SvelteKit:底层基于vite的更上层框架,类似于nextjs。

npm create svelte@latest my-app
cd my-app
npm install
npm run dev

.svelte文件结构

和vue类似svelte文件是.svelte结尾的文件,比如demo.svelte。代码结构:

<script>
  let name = 'hello world';
</script>

<div class="name">
  {name}
</div>

<style>
.name {
  color: red;
}
</style>

模版绑定

绑定变量

<script>
  let name = 'world';
</script>

<h1>Hello {name}!</h1>

绑定属性

<script>
  let src = '/tutorial/image.gif';
  let name = '张三';
</script>

<img {src} alt="{name} dances.">

绑定事件

<script>
  let count = 0;

  function incrementCount() {
    count += 1;
  }
</script>

<button on:click={incrementCount}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

$:类似于vue的computed。例如:

<script>
  let count = 0;
    // 定义一个名字叫doubled的变量,当count的值改变时,doubled会改变。doubled变量时响应式的。
  $: doubled = count * 2;
    // 直接这样写d2不是响应式的。
  let d2 = count * 2;

    $: if (count >= 10) {
        alert('count is dangerously high!');
        count = 9;
    }

    $: {
        console.log('the count is ' + count);
        alert('I SAID THE COUNT IS ' + count);
    }

  function handleClick() {
    count += 1;
  }
</script>

<button on:click={handleClick}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

<p>{count} doubled is {doubled}</p>
<p>
  t2 is {d2}
</p>

为什么d2变量不是响应式的,我们会在 svelte响应式原理里面解释。
if/else

	  <script>
	  	let user = { loggedIn: false };

	  	function toggle() {
	  		user.loggedIn = !user.loggedIn;
	  	}
	  </script>

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

each遍历

<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 { id, name }, i}
    <li><a target="_blank" href="https://www.youtube.com/watch?v={id}" rel="noreferrer">
      {i + 1}: {name}
    </a></li>
  {/each}
</ul>

await

<script>
  async function getRandomNumber() {
    const res = await fetch(`/tutorial/random-number`);
    const text = await res.text();

    if (res.ok) {
      return {val: text};
    } else {
      throw new Error(text);
    }
  }

  let promise = getRandomNumber();

  function handleClick() {
    promise = getRandomNumber();
  }
</script>

<button on:click={handleClick}>
  generate random number
</button>

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

双向数据流

<script>
  let name = 'world';
    $:
</script>

<input bind:value={name}>

<h1>Hello {name}!</h1>

组件

使用子组件和父子组件通信
App.svelte

<script lang="ts">
  import Child from './child.svelte';

  var num = 1;
    var obj = {
      count: 1
    }

  function handleAdd() {
    num = num + 1;
        obj.count = obj.count + 1;
  }

    function handleReset(event) {
    num = event.detail.val;
    obj.count = event.detail.val;
  }
</script>

<div>
  我是父组件
  <button on:click={handleAdd}>add num</button>
    // 也支持...的语法
  <Child count={num} on:reset={handleReset} />
    <Child {...obj} on:reset={handleReset} />
</div>

Child.svelte

<script>
  import { createEventDispatcher } from 'svelte';
  export let count;

  const dispatch = createEventDispatcher();

  function handleReset() {
    dispatch('reset', {
      val: 0
    });
  }
</script>

<div>
  <p>我是子组件,count is {count}</p>
  <button on:click={handleReset}>reset count</button>
</div>

组件中使用双向数据流
App.svelte

<script>
  import Child from './child.svelte';

  var name;
</script>

<p>
  name is {name}
</p>
<Child bind:name />

Child.svelte

<script>
  export let name;
</script>

<div>
  <input bind:value={name} />
</div>

插槽
App.svelte

<script>
  import Child from './child.svelte';
</script>

<Child>
  <p>i am from App</p>
  <p slot="tool">i am tool</p>
</Child>

Child.svelte

<div>
  <slot />
  <slot name="tool" />
</div>

生命周期

onMount、onDestroy、beforeUpdate、afterUpdate

<script>
  import { onMount, onDestroy, beforeUpdate, afterUpdate } from 'svelte';

  onMount(() => {
    //...
  });

  onDestroy(() => {
    //...
  });

    beforeUpdate(() => {
    //...
  });

    afterUpdate(() => {
    //...
  });
</script>

<h1>Photo album</h1>