Svelte之基础知识一

参考资料

什么是Svelte?

  • Svelte 是一个构建 web 应用程序的工具
  • Svelte 与诸如 React 和 Vue 等 JavaScript 框架类似,都怀揣着一颗让构建交互式用户界面变得更容易的心。
    但是有一个关键的区别:Svelte 在 构建/编译阶段 将你的应用程序转换为理想的 JavaScript 应用,而不是在 运行阶段 解释应用程序的代码。这意味着你不需要为框架所消耗的性能付出成本,并且在应用程序首次加载时没有额外损失。
    你可以使用 Svelte 构建整个应用程序,也可以逐步将其融合到现有的代码中。你还可以将组件作为独立的包(package)交付到任何地方,并且不会有传统框架所带来的额外开销。

简介

添加数据{}

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

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

对比Vue:{{}} => {}

动态属性{}

<script>
	let src = 'tutorial/image.gif';
	let name = 'Rick Astley';
</script>

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

对比Vue::src = "" => src={}

嵌套组件

注意:组件名称 Nested 的首字母大写。采用此约定是为了使我们能够区分用户自定义的组件和一般的 HTML 标签。

<script>
	import Nested from './Nested.svelte';
</script>

<style>
	p {
		color: purple;
		font-family: 'Comic Sans MS', cursive;
		font-size: 2em;
	}
</style>

<p>This is a paragraph.</p>
<Nested/>

HTML标签@html

<script>
	let string = `this string contains some <strong>HTML!!!</strong>`;
</script>

<p>{@html string}</p>

对比Vue:v-html => @html

创建一个应用程序

反应性能力

赋值on:click={}

<script>
	let count = 0;

	function handleClick() {
		count++;
		// event handler code goes here
	}
</script>

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

对比Vue:@click="" => on:click={}

声明$:

<script>
	let count = 0;
	$: doubled = count * 2

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

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

对比Vue:computed => $:

语句$:{}

<script>
	let count = 0;
	$: console.log(`the count is ${count}`)
	$: {
		console.log(`the count is ${count}`)
		alert(`the count is ${count}`)
	}
	$: if (count >= 2){
		console.log(`the count is ${count}`)
		alert(`count is dangerously high ${count}`)
	}
	
	function handleClick() {
		count += 1;
	}
</script>

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

更新数组和对象

  • 由于 Svelte 的反应性是由赋值语句触发的,因此使用数组的诸如 push 和 splice 之类的方法就不会触发自动更新。
  • 解决该问题的一种方法是添加一个多余的赋值语句
  • 一个简单的经验法则是:被更新的变量的名称必须出现在赋值语句的左侧
	<script>
		let numbers = [1, 2, 3, 4];

		function addNumber() {
			numbers = [...numbers, numbers.length + 1]
			numbers[numbers.length] = numbers.length + 1;
		}

		const obj = {foo: {bar: 1}}
		const foo = obj.foo;
	  foo.bar = 'baz';

		$: sum = numbers.reduce((t, n) => t + n, 0);
	</script>

	<p>{numbers.join(' + ')} = {sum}</p>

	<button on:click={addNumber}>
		Add a number
	</button>
	<p>
		{obj.foo.bar}
	</p>

属性

Declaring propsexport

  • 用于父子组件传值
    子组件:
	<script>
		export let answer;
	</script>

	<p>The answer is {answer}</p>

父组件:

	<script>
		import Nested from './Nested.svelte';

	</script>

	<Nested answer={412122}/>

对比Vue:prop => export

属性对象传递{...xxx}

<script>
	import Info from './Info.svelte';

	const pkg = {
		name: 'svelte',
		version: 3,
		speed: 'blazing',
		website: 'https://svelte.dev'
	};
</script>

<Info {...pkg}/>

逻辑

if语句{#if xxx}...{/if}

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

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

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

对比vue:v-if=>{#if xxx}...{/if}

else语句{#if xxx}...{:else}...{/if}

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

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

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

对比vue:v-if v-else=>{#if xxx}...{:else}...{/if}

else-if语句{#if xxx}...{:else if xxx}...{:else}...{/if}

<script>
	let x = 7;
</script>

{#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}

each语句{#each xxx as xx}...{/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>
	<!-- open each block -->
	{#each cats as cat, i}
		<li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
			{i + 1}:{cat.name}
		</a></li>
	{/each}
	<!-- close each block -->
</ul>

对比vue:v-for=>{#each xxx as xx}...{/each}

为each语句添加key值{#each xxx as xx(key-xxx)}...{/each}

<script>
	import Thing from './Thing.svelte';

	let things = [
		{ id: 1, color: '#0d0887' },
		{ id: 2, color: '#6a00a8' },
		{ id: 3, color: '#b12a90' },
		{ id: 4, color: '#e16462' },
		{ id: 5, color: '#fca636' }
	];

	function handleClick() {
		things = things.slice(1);
	}
</script>

<button on:click={handleClick}>
	Remove first thing
</button>

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

对比vue::key="key-xxx"=>{#each xxx as xx(key-xxx)}...{/each}

await语句{#await xxx}...{:then xxx}...{:catch error}...{/await}

<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}
<p>waiting</p>
{:then value}
<p>
	{value}
</p>
{:catch error}
<p>
	{error}
</p>
{/await}

<!-- 方法二:省略 -->
{#await promise then value}
<p>{value}</p>
{/await}

事件

DOM 事件on:xxx={xxx}

<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>

inline handlers

<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={e => m = {x: e.clientX, y: e.clientY}}>
	The mouse position is {m.x} x {m.y}
</div>

事件修饰器on:xxx|once

所有修饰符列表:

  • preventDefault :调用event.preventDefault() ,在运行处理程序之前调用。比如,对客户端表单处理有用。
  • stopPropagation :调用 event.stopPropagation(), 防止事件影响到下一个元素。
  • passive : 优化了对 touch/wheel 事件的滚动表现(Svelte 会在合适的地方自动添加滚动条)。
  • capture — 在 capture 阶段而不是bubbling 阶段触发事件处理程序 ()
  • once :运行一次事件处理程序后将其删除。
  • self — 仅当 event.target 是其本身时才执行。
	<script>
		function handleClick() {
			alert('clicked')
		}
	</script>

	<button on:click|once={handleClick}>
		Click me
	</button>
  • 可以将修饰符组合在一起使用,例如:on:click|once|capture={...}

组件事件

  • 子组件:createEventDispatcher()(‘xxx’, param)
    createEventDispatcher 必须在首次实例化组件时调用它,—组件本身不支持如 setTimeout 之类的事件回调。 定义一个dispatch进行连接,进而把组件实例化。
	<script>
		import { createEventDispatcher } from 'svelte';
		// setup code goes here
		const dispatch = createEventDispatcher()

		function sayHello() {
			dispatch('message', {
				text: 'Hello zoey'
			})
		}
	</script>

	<button on:click={sayHello}>
		Click to say hello zoey
	</button>
  • 父组件:on:xxx
	<script>
		import Inner from './Inner.svelte';

		function handleMessage(event) {
			alert(event.detail.text);
		}
	</script>

	<Inner on:message={handleMessage}/>

事件转发on:messageon:click

message 没有赋予特定的值得情况下意味着转发所有massage事件:

<script>
	import Inner from './Inner.svelte';
</script>

<Inner on:message/>
  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值