svelte初探-下

Actions(Svelte的自定义指令)
  • 本质上就是元素级别的生命周期,可以类比vue的directives。
  • 在元素上使用use:xxx的方式使用一个action,action的实现方式与普通函数类似
  • action函数中通常需要return一个deatroy()函数以便在组件卸载时触发相关事件,例如定时器或者事件监听等
  • action一般使用dispatchEvent的方式来暴露action.js中的事件,可以在外部使用"on:事件名" 的形式来监听对应抛出的事件
  • 如果绑定的action需要传递一些参数可以使用 use:xxx={a,b,c}的形式传递,在action.js中使用直接设置形参就可以了
// app.svelte
<script>
	import { spring } from 'svelte/motion';
	const coords = spring({ x: 0, y: 0 }, {
		stiffness: 0.2,
		damping: 0.4
	});
	function handlePanStart() {
		coords.stiffness = coords.damping = 1;
	}
	function handlePanMove(event) {
		coords.update($coords => ({
			x: $coords.x + event.detail.dx,
			y: $coords.y + event.detail.dy
		}));
	}
	function handlePanEnd(event) {
		coords.stiffness = 0.2;
		coords.damping = 0.4;
		coords.set({ x: 0, y: 0 });
	}
</script>
<style>
	.box {
		--width: 100px;
		--height: 100px;
		position: absolute;
		width: var(--width);
		height: var(--height);
		left: calc(50% - var(--width) / 2);
		top: calc(50% - var(--height) / 2);
		border-radius: 4px;
		background-color: #ff3e00;
		cursor: move;
	}
</style>
<div class="box"
	on:panstart={handlePanStart}
	on:panmove={handlePanMove}
	on:panend={handlePanEnd}
	style="transform:
		translate({$coords.x}px,{$coords.y}px)
		rotate({$coords.x * 0.2}deg)"
></div>
// pannable.js
export function pannable(node) {
	let x;
	let y;
	function handleMousedown(event) {
		x = event.clientX;
		y = event.clientY;
		node.dispatchEvent(new CustomEvent('panstart', {
			detail: { x, y }
		}));
		window.addEventListener('mousemove', handleMousemove);
		window.addEventListener('mouseup', handleMouseup);
	}
	function handleMousemove(event) {
		const dx = event.clientX - x;
		const dy = event.clientY - y;
		x = event.clientX;
		y = event.clientY;
		node.dispatchEvent(new CustomEvent('panmove', {
			detail: { x, y, dx, dy }
		}));
	}
	function handleMouseup(event) {
		x = event.clientX;
		y = event.clientY;
		node.dispatchEvent(new CustomEvent('panend', {
			detail: { x, y }
		}));
		window.removeEventListener('mousemove', handleMousemove);
		window.removeEventListener('mouseup', handleMouseup);
	}
	node.addEventListener('mousedown', handleMousedown);
	return {
		destroy() {
			node.removeEventListener('mousedown',handleMousedown);
		}
	};
}
Classes(类比vue的class绑定)
  • 可以使用js表达式动态设置设置一个class
<button
	class="{current === 'foo' ? 'selected' : ''}"
	on:click="{() => current = 'foo'}"
>foo</button>

<button
	class:selected="{current === 'foo'}"
	on:click="{() => current = 'foo'}"
>foo</button>

<div class:big={big}>
	<!-- ... -->
</div>
// 可以简写为:
<div class:big>
	<!-- ... -->
</div>
组件Slot插槽
  • slot是一个插槽出口,标记了父元素提供的插槽内容应该被渲染的位置
  • Svelte插槽与vue插槽一样也有匿名插槽与具名插槽
  • 匿名插槽会将组件内容渲染到默认位置,具名插槽会将在指定的位置替换内容
  • $$slots是一个包含父组件左右插槽key值的对象,如果父组件中的具名插槽内容为空则不会有该插槽的入口,可以用来判断插槽内容是否存在。
  • 可以使用 let:a={a} 来暴露组件内的内容,在{}中可以将插槽传递过来的参数重新命名使用。
// app.svelte
<script>
	import ContactCard from './ContactCard.svelte';
</script>
<ContactCard>
	<span slot="name">
		P. Sherman
	</span>
	<span slot="address">
		42 Wallaby Way<br>
		Sydney
	</span>
</ContactCard>
// contactCard.svelte
<style>
	.contact-card {
		width: 300px;
		border: 1px solid #aaa;
		border-radius: 2px;
		box-shadow: 2px 2px 8px rgba(0,0,0,0.1);
		padding: 1em;
	}
	h2 {
		padding: 0 0 0.2em 0;
		margin: 0 0 1em 0;
		border-bottom: 1px solid #ff3e00
	}
	.address, .email {
		padding: 0 0 0 1.5em;
		background:  0 0 no-repeat;
		background-size: 20px 20px;
		margin: 0 0 0.5em 0;
		line-height: 1.2;
	}
	.address { background-image: url(tutorial/icons/map-marker.svg) }
	.email   { background-image: url(tutorial/icons/email.svg) }
	.missing { color: #999 }
</style>
<article class="contact-card">
	<h2>
		<slot name="name">
			<span class="missing">Unknown name</span>
		</slot>
	</h2>
	<div class="address">
		<slot name="address">
			<span class="missing">Unknown address</span>
		</slot>
	</div>
	<div class="email">
		<slot name="email">
			<span class="missing">Unknown email</span>
		</slot>
	</div>
</article>
context API
  • setContext(key,context)
  • getContext(key)
  • contextAPI提供了一个机制可以让组件实现在不使用props及各种繁杂的events下实现互相通信

待续。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值