Svelte 的核心思想在于『通过静态编译减少框架运行时的代码量』。通俗来说,用
svelte
写的代码,经过编译处理,转化成了真正的js
,不需要引入相应的库,不像vue
项目需要引入vue.js
、用写jQuery
代码需要引入jQuery
。
三大框架(vue/react/angular)已经趋于成熟,为何会出现svelte
?假如我们写了以下代码:
<h1>{title}</h1>
目的是:title
作为h1
初始内容,当title
发生变化时h1
内容跟着更新。想要实现这一目标,最简单的方法就是直接渲染出 HTML
,然后设置到innerHTML
中,但是当模板结构复杂时会带来很严重的性能问题。
虚拟DOM
就是用来解决此种方案性能问题的,当状态发生变化时,新旧虚拟DOM
树进行对比,然后只将少数差异的部分 patch
到真实 DOM
上,就能极大地提高性能。
这段代码就是要动态更新h1
标签内容而已,每次数据发生变化都要生成新的DOM
树->diff
->patch
,不是很有必要!
接下来看看svelte
的骚操作,它会将这段模板编译成下面这段js
:
function renderMainFragment ( root, component, target ) {
var node = document.createElement( 'h1' );
var text = document.createTextNode( root.title );
node.appendChild( text );
target.appendChild( node )
return {
update( changed, root ) {
//数据变化时更新文本节点内容
text.data = root.title;
},
teardown: function ( detach ) {
//销毁时移除节点
if ( detach ) node.parentNode.removeChild( node );
}
};
}
通过上面的描述,相信大家对svelte
有一定了解了,接下来一睹芳容。
想快速尝鲜的可以去官网coding online 网址:svelte.dev
下面简单介绍框架的核心概念:
1.文件结构(以.svelte为后缀)
<script>
//js中的根变量即为状态 可在模板中插值
let title="hello svelte"
</script>
<style>
p {
color: purple;
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
}
</style>
<h1>{title}</h1>
2.属性插值
<script>
let src = 'tutorial/image.gif';
let name = 'Rick Astley';
</script>
<!-- {src} 是 src={src} 的简写 -->
<img {src} alt="{name} dancing">
3.标签插值解析HTML
<script>
let text = `<strong>重要内容</strong>`;
</script>
<p>{@html text}</p>
4.条件语句
<script>
let login=true
</script>
{#if login}
<button>
退出登录
</button>
{/if}
{#if !login}
<button>
登录
</button>
{/if}
5.遍历
<script>
let list = [
{ id: 1, color: '#0d0887' },
{ id: 2, color: '#6a00a8' },
{ id: 3, color: '#b12a90' },
{ id: 4, color: '#e16462' },
{ id: 5, color: '#fca636' }
];
</script>
<ul>
<!-- item:值 index:索引 小括号内:key -->
{#each list as item,index (item.id)}
<li>{item.color}-----{index}</li>
{/each}
</ul>
6.事件处理
<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>
7.分割组件
<!-- -----list.svelte -->
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<!-- -----app.svelte -->
<script>
//组件首字母大写
import List from './list.svelte';
</script>
<List/>
8.组件传值 props
<!-- -----child.svelte -->
<script>
export let title;
//可以指定默认值
//export let title=123
</script>
<h1>
{title}
</h1>
<!-- -----app.svelte -->
<script>
//组件首字母大写
import Child from './child.svelte';
</script>
<Child title="hello svelte"/>
9.自定义事件
<!-- -----app.svelte -->
<script>
import Inner from './Inner.svelte';
function handleMessage(event) {
alert(event.detail.text);
}
</script>
<Inner on:message={handleMessage}/>
<!-- -----Inner.svelte -->
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function sayHello() {
dispatch('message', {
text: 'Hello!'
});
}
</script>
<button on:click={sayHello}>
Click to say hello
</button>
10.表单双向绑定
<script>
let name = '';
</script>
<input bind:value={name} placeholder="enter your name">
<p>Hello {name || 'stranger'}!</p>
<script>
let yes = false;
</script>
<label>
<input type=checkbox bind:checked={yes}>
{yes}
</label>
<script>
let questions = [
{ id: 1, text: `Where did you go to school?` },
{ id: 2, text: `What is your mother's name?` },
{ id: 3, text: `What is another personal fact that an attacker could easily find with Google?` }
];
let selected;
let answer = '';
</script>
<select bind:value={selected}>
{#each questions as question}
<option value={question.text}>
{question.text}
</option>
{/each}
</select>
<h1>{selected}</h1>
11.生命周期函数
onMount
<script>
import { onMount } from 'svelte';
let list = [];
let getData = async ()=>{
let res = await ajax("/getData") ;
list=res.data;
}
//挂在完成 可用于请求初始化数据
onMount(async () => {
getData();
});
</script>
tick 状态变化DOM更新之后
<script>
import { tick } from 'svelte';
let num=1
let handle = async (e)=>{
num++;
console.log(e.target.innerText) //1;
await tick();
console.log(e.target.innerText) //2;
}
</script>
<button on:click="{handle}">{num}</button>