svelte 学习记录(一)
svtelte 是一款更小、更轻量的框架,比现在的三大框架都更轻量,但是应用不广泛。之中的利弊可以移步知乎等论坛
https://www.zhihu.com/question/53150351
Hello world
和vue 比较类似,他也有自己独特的 .svelte 后缀的文件
app.svelte
<h1>Hello world!</h1>
这个文件会输出对应的 html、js和css 代码,(简直是比vue还要精简)
动态绑定变量
<script>
let name = 'world';
</script><h1>Hello {name}!</h1>
用 {} 号将script 中的变量绑定到html中,和jsx语法类似
动态绑定属性
<script>
let src = 'tutorial/image.gif'
</script><img src={src}/>
// 或者简写
<img {src}/>
css 样式
通过<style> 中写样式
<style>p {color: purple;font-family: 'Comic Sans MS', cursive;font-size: 2em;}
</style><p>This is a paragraph.</p>
引入组件
<script>中import 需要的组件 调用就可以了
<script>import Nested from './Nested.svelte';
</script><p>This is a paragraph.</p>
<Nested/>
引入html 代码片段
通过@html 使用html代码片段,不要忘记之后加个空格哦
<script>let string = `this string contains some <strong>HTML!!!</strong>`;
</script><p>{{@html string}</p>
svelte 开发工具插件
- rollup-plugin-svelte
- svelte-loader
更多其他工具
挂在到实际节点上
import App from './App.svelte';const app = new App({target: document.body,props: {// we'll learn about props lateranswer: 42}
});
响应式编程
通过on:click 绑定点击事件 修改变量之后{} 赋值
<script>let count = 0;function handleClick() {count += 1;}
</script><button on:click={handleClick}>Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
计算属性
类似vue的computed ,通过$:声明一个变量
<script>let count = 0;$: doubled = count * 2;function handleClick() {count += 1;}
</script><button on:click={handleClick}>Clicked {doubled} {count === 1 ? 'time' : 'times'}
</button>
// 等价于 {count * 2}
监听变量
通过$: 之后执行代码,来监听变量,还可加条件监听,类似 react的useEffect 或vue的watch
// case 1
$: console.log(`the count is ${count}`);// case 2$: {console.log(`the count is ${count}`);alert(`I SAID THE COUNT IS ${count}`);
}// case 3
$: if (count >= 10) {alert(`count is dangerously high!`);count = 9;
}
解决修改array或object 更新问题
数组push、pop、
shift
、unshift
和 splice
不会触发更新,解决办法就是重新 =
// case 1
function addNumber() {numbers.push(numbers.length + 1);numbers = numbers;
}// case 2 (惯用套路)function addNumber() {numbers = [...numbers, numbers.length + 1];
}
操作属性也是可以触发更新的
function addNumber() {numbers[numbers.length] = numbers.length + 1;
}function addNumber() {numbers.b += 1;
}
object 传递引用修改无效
const foo = obj.foo;
foo.bar = 'baz';// 解决方法
obj = obj;
props 声明
通过export 对外声明组件变量
<script>export let answer;// 这样写 2 为anwer的默认值export let answer = 2;
</script><p>The answer is {answer}</p>
通过三点表达式 简化传递属性
<Info {...pkg}/>
还可以使用$$props获取未声明传递的属性 类似react jsx写法
逻辑判断
if语句
{#if} 开始判断 {:else}{:else if}中间拼接 {/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}//或者
{#if user.loggedIn}<button on:click={toggle}>Log out</button>
{:else}<button on:click={toggle}>Log in</button>
{/if}
for 循环
cats 是item 、 i是索引值
{#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}
列表渲染key
id 作为key ,利于正确更新 。默认用thing 更新,会造成更新异常
{#each things as thing (thing.id)}<Thing current={thing.color}/>
{/each}
await 代码块
利于promise 处理,用于网络请求
{#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 value}<p>the value is {value}</p>
{/await}
事件
通过 on: 绑定事件
<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>// 不建议这样绑定
<div on:mousemove={e=>m={x:e.clientX,y:e.clientY}}>The mouse position is {m.x} x {m.y}
</div>
事件绑定修饰符
- once : 绑定事件只执行一次
- preventDefault: 执行时 event.preventDefault()
- stopPropagation: 执行时 event.stopPropagation()
- passive : 提高scroll事件滚动流畅的效果
- capture : 事件捕获
- self: 事件发生对象为绑定对象触发。
on:click|once|capture={...} 链式 类似vue 语法.stop
<script>function handleClick() {alert('no more alerts')}
</script><button on:click|once={handleClick}>Click me
</button>
组件的自定义事件
通过createEventDispatcher 创建事件触发器 dispatch
<script>import { createEventDispatcher } from 'svelte';const dispatch = createEventDispatcher();function sayHello() {dispatch('message', {text: 'Hello!'});}
</script>
注意自定义事件不会冒泡 、所以需要中间组件进行事件转发。通过event.detail 传递
<script>import Inner from './Inner.svelte';import { createEventDispatcher } from 'svelte';const dispatch = createEventDispatcher();function forward(event) {dispatch('message', event.detail);}
</script><Inner on:message={forward}/>
简写
<script>import Inner from './Inner.svelte';
</script><Inner on:message/>
双向绑定
通过bind: 双向绑定进行绑定值
<script>let name = 'world';
</script><input bind:value={name}><h1>Hello {name}!</h1>
<script>let a = 1;let b = 2;
</script><label>
// 自动处理<input type=number bind:value={a} min=0 max=10><input type=range bind:value={a} min=0 max=10>
</label><label><input type=number bind:value={b} min=0 max=10><input type=range bind:value={b} min=0 max=10>
</label><p>{a} + {b} = {a + b}</p>
<label><input type=checkbox bind:checked={yes}>Yes! Send me regular email spam
</label>
使用bind:group处理 单选按钮组或者多选按钮组
<script>let scoops = 1;let flavours = ['Mint choc chip'];function join(flavours) {if (flavours.length === 1) return flavours[0];return `${flavours.slice(0, -1).join(', ')} and ${flavours[flavours.length - 1]}`;}
</script><h2>Size</h2><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><h2>Flavours</h2><label><input type=checkbox bind:group={flavours} value="Cookies and cream">Cookies and cream
</label><label><input type=checkbox bind:group={flavours} value="Mint choc chip">Mint choc chip
</label><label><input type=checkbox bind:group={flavours} value="Raspberry ripple">Raspberry ripple
</label>{#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 {join(flavours)}</p>
{/if}
<textarea bind:value={value}></textarea>
<select bind:value={selected} on:change="{() => answer = ''}"><select multiple bind:value={flavours}>{#each menu as flavour}<option value={flavour}>{flavour}</option>{/each}
</select>
动态绑定富文本代码片段
<divcontenteditable="true"bind:innerHTML={html}
></div>
video 、audio标签绑定
- duration(只读):视频总时间
- buffered(只读):一个数组包含{start, end}对象
- seekable(只读):
- played(只读):
- seeking(只读):
- ended(只读):
其他四个 可以双向绑定的
- currentTime: 当前进度
- playbackRate:播放速度 设置1为正常速度
- paused : 暂停
- volume: 音量大小 0到1
<videoposter="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"on:mousemove={handleMousemove}on:mousedown={handleMousedown}bind:currentTime={time}bind:durationbind:paused
></video>
任何块状元素都有属性clientWidth
, clientHeight
, offsetWidth
和 offsetHeight
(都是只读)
<div bind:clientWidth={w} bind:clientHeight={h}><span style="font-size: {size}px">{text}</span>
</div>
通过bind:this 获取节点本身,必须要mounted后才能渲染到。 类似 react和vue 的ref
<canvasbind:this={canvas}width={32}height={32}
></canvas>
绑定组件的自定义属性
<Keypad bind:value={pin} on:submit={handleSubmit}/>
生命周期
onMount 生命周期应用广泛你可以在这边,初始化发起http请求。
注意:在SSR环境中。除了onDestroy ,其他生命周期都不会触发.
要在组件初始化的时候,调用生命周期的钩子函数,不要在setTimeout中使用
onMount 如果返回一个方法,那个方法会在组件销毁时候调用。类似react 的useEffect
<script>import { onMount } from 'svelte';let photos = [];onMount(async () => {const res = await fetch(`https://jsonplaceholder.typicode.com/photos?_limit=20`);photos = await res.json();});
</script>
onDestory 组件销毁时候调用。比如说setInterval 。避免内存泄漏
<script>import { onDestroy } from 'svelte';let seconds = 0;const interval = setInterval(() => seconds += 1, 1000);onDestroy(() => clearInterval(interval));
</script>
可以封装一下类似react hooks 的工具
// utils.js
import { onDestroy } from 'svelte';export function onInterval(callback, milliseconds) {const interval = setInterval(callback, milliseconds);onDestroy(() => {clearInterval(interval);});
}
// 在组件中使用
<script>import { onInterval } from './utils.js';let seconds = 0;onInterval(() => seconds += 1, 1000);
</script>
beforeUpdate 和 afterUpdate 用于组件更新时候的hook(吐槽下: 官方的例子真的是简洁易懂)
<script>import Eliza from 'elizabot';import { beforeUpdate, afterUpdate } from 'svelte';let div;let autoscroll;beforeUpdate(() => {autoscroll = div && (div.offsetHeight + div.scrollTop) > (div.scrollHeight - 20);});afterUpdate(() => {if(autoscroll) div.scrollTo(0,div.scrollHeight)});const eliza = new Eliza();let comments = [{ author: 'eliza', text: eliza.getInitial() }];function handleKeydown(event) {if (event.which === 13) {const text = event.target.value;if (!text) return;comments = comments.concat({author: 'user',text});event.target.value = '';const reply = eliza.transform(text);setTimeout(() => {comments = comments.concat({author: 'eliza',text: '...',placeholder: true});setTimeout(() => {comments = comments.filter(comment => !comment.placeholder).concat({author: 'eliza',text: reply});}, 500 + Math.random() * 500);}, 200 + Math.random() * 200);}}
</script><style>.chat {display: flex;flex-direction: column;height: 100%;max-width: 320px;}.scrollable {flex: 1 1 auto;border-top: 1px solid #eee;margin: 0 0 0.5em 0;overflow-y: auto;}article {margin: 0.5em 0;}.user {text-align: right;}span {padding: 0.5em 1em;display: inline-block;}.eliza span {background-color: #eee;border-radius: 1em 1em 1em 0;}.user span {background-color: #0074D9;color: white;border-radius: 1em 1em 0 1em;word-break: break-all;}
</style><div class="chat"><h1>Eliza</h1><div class="scrollable" bind:this={div}>{#each comments as comment}<article class={comment.author}><span>{comment.text}</span></article>{/each}</div><input on:keydown={handleKeydown}>
</div>
tick 神奇的hooks ,不只再组件初始化的时候可以调用
<script>import {tick} from 'svelte';let text = `Select some text and hit the tab key to toggle uppercase`;async function handleKeydown(event) {if (event.which !== 9) return;event.preventDefault();const { selectionStart, selectionEnd, value } = this;const selection = value.slice(selectionStart, selectionEnd);const replacement = /[a-z]/.test(selection)? selection.toUpperCase(): selection.toLowerCase();text = (value.slice(0, selectionStart) +replacement +value.slice(selectionEnd));await tick() // 再执行后面代码前,先把之前代码执行完成this.selectionStart = selectionStart;this.selectionEnd = selectionEnd;}
</script><style>textarea {width: 100%;height: 200px;}
</style><textarea value={text} on:keydown={handleKeydown}></textarea>
svelte 学习记录(一)相关推荐
- Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)
Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...
- HTML5与CSS3权威指南之CSS3学习记录
title: HTML5与CSS3权威指南之CSS3学习记录 toc: true date: 2018-10-14 00:06:09 学习资料--<HTML5与CSS3权威指南>(第3版) ...
- springboot @cacheable不起作用_Springboot学习记录13 使用缓存:整合redis
本学习记录的代码,部分参考自gitee码云的如下工程.这个工程有详尽的Spingboot1.x教程.鸣谢! https://gitee.com/didispace/SpringBoot-Learnin ...
- 【Cmake】Cmake学习记录
Cmake学习记录 1.1 常例 add_library(gen_reference_infogen_reference_info/gen_reference_info.hgen_reference_ ...
- ASP.NETCore学习记录(一)
ASP.NETCore学习记录(一) asp.net core介绍 Startup.cs ConfigureServices Configure 0. ASP.NETCore 介绍 ASP.N ...
- Android开发技术周报176学习记录
Android开发技术周报176学习记录 教程 当 OkHttp 遇上 Http 2.0 http://fucknmb.com/2018/04/16/%E5%BD%93OkHttp%E9%81%87% ...
- add函数 pytorch_Pytorch学习记录-Pytorch可视化使用tensorboardX
Pytorch学习记录-Pytorch可视化使用tensorboardX 在很早很早以前(至少一个半月),我做过几节关于tensorboard的学习记录. https://www.jianshu.co ...
- java之字符串学习记录
java之字符串学习记录 public class StringDemo { public static void main(String[] args) { //静态初始化字符串 String s1 ...
- Redis的学习记录
Redis的学习记录 1.先导了解 1.1 NOSQL概述 1.1.1 为什么要用NoSql? 1.1.2 NoSql了解 1.1.3 NoSql特点 1.1.4 NoSQL的四大分类 2. Redi ...
最新文章
- 零基础入门jQuery视频教程
- 无聊写的一个PHP Socket类
- Fiori elements执行过程解析:When click go in table list, odata service is sent
- linux runqueue定义,Linux中多CPU的runqueue及抢占
- html 自定义文件选择,html5 自定义文件上传
- Linux磁盘、内存、CPU、进程
- redis 哨兵 异步_Redis稍微往上一点点写点集群
- 国内域名国内服务器,不备案解决80端口不开放方法
- 通用量子计算机和容错量子计算,量子计算机研究(下册)——纠错和容错计算...
- Access把每一天的数据累加_SQL 数据库语句大全
- 如何用安装启动盘启动计算机,如何使用U盘启动进入PE安装系统,小编教你如何安装...
- elasticsearch forcemerge
- P4017 最大食物链计数
- 迷宫寻径问题(数据结构4.4.3)
- SAS:字符串常用函数简介
- 任天堂官网在哪里修改服务器,任天堂服务器设置
- 用户流失200万、资金池疑似见了底,摩拜靠什么拿到下一轮融资?
- 【计算机视觉】数字图像处理(六)—— 图像压缩
- rt1052 usb速率_如何才能赋予RT1052超级视频编解码能力?
- 【图像分割】基于snake模型的图像分割matlab 源码
热门文章
- 9018单管调频话筒调试攻略
- linux进程sl,Linux ps state sl+是什么意思
- 如何面对「加班文化」?
- Android11.0(R) 预置 wifi 信息自动连接
- 【操作系统】操作系统纠错本
- 索尼播放器Android系统,好物推荐 | 索尼ZX505:Android系统的播放器香不香?
- 利用圆圈轮廓面积求取圆环半径:cv2.findContours, contourArea
- skynet lua 代码静态分析
- 如何将QQ聊天记录保存或导入到新安装的QQ里面!
- NSGA_II学习案例1