目录
前言
一、编译阶段
1. 导入语句
2. 组件声明
3. 模板部分
4. CSS样式
二、运行时阶段
三、生命周期函数
1. onMount
2. beforeUpdate 与 afterUpdate
3. onDestroy
4. setContext 与 getContext
6. hasContext
7. getAllContexts
前言
Svelte是一种现代的JavaScript框架,用于构建高效且响应式的Web应用程序。它采用了独特的编译方式,将组件编译为高效的原生代码,从而提供更好的性能和用户体验。在Svelte的生命周期中,有许多重要的阶段,包括编译、运行时和组件的生命周期。
一、编译阶段
Svelte的编译阶段主要涉及将Svelte组件转换为可执行的JavaScript代码。在Svelte中,组件通常以.svelte文件的形式存在,并使用特殊的语法和指令。在编译过程中,Svelte编译器会解析组件文件,并将其转换为可执行的JavaScript代码。
1. 导入语句
在Svelte中,可以使用<script>
标签导入所需的JavaScript模块。例如:
<script>
import { add } from './math.js';
</script>
2. 组件声明
在Svelte中,可以使用<script>
标签声明组件的逻辑部分。例如:
<script>
let count = 0;
function increment() {
count++;
}
</script>
3. 模板部分
在Svelte中,可以使用HTML语法来定义组件的外观和结构。例如:
<h1>Hello, World!</h1>
<button on:click={increment}>Increment</button>
4. CSS样式
在Svelte中,可以使用CSS语法来定义组件的样式。例如:
<style>
h1 {
color: red;
}
</style>
在编译阶段结束时,Svelte编译器将生成可执行的JavaScript代码,用于在浏览器中运行。
强推svelte官网提供的REPL,可供学习和查看编译后的代码!
二、运行时阶段
在运行时阶段,Svelte应用程序开始执行并响应用户的交互。Svelte应用程序由多个组件组成,每个组件都包含一个独立的运行时环境。当用户与应用程序交互时,每个组件都会根据其逻辑和模板进行相应的更新和渲染。
创建组件实例:在Svelte应用程序中,每个组件都是一个独立的实例。当组件被加载时,Svelte会创建一个新的实例,并将其存储在内存中。
更新状态:当用户与应用程序交互时,组件的状态可能会发生变化。例如,当用户点击按钮时,计数器的值会增加。这些状态变化将触发组件的更新和重新渲染。
重新渲染:当组件的状态发生变化时,Svelte会重新计算组件的外观和结构,并更新DOM。在Svelte中,重新渲染是一个轻量级的操作,因为只有在状态发生变化时才会进行。这使得Svelte具有很高的性能和响应性。
销毁组件:当组件不再需要时,Svelte会将其从内存中删除,以释放资源。在销毁过程中,组件的生命周期函数将被调用,以便进行必要的清理和资源释放。
三、生命周期函数
1. onMount
在组件挂载到DOM后执行。常用于初始化异步操作或执行DOM操作。
<script>
import { onMount } from 'svelte';
onMount(() => {
// 在组件被插入到 DOM 后执行初始化操作
console.log('组件已插入到 DOM');
});
</script>
2. beforeUpdate 与 afterUpdate
在组件更新之前和之后触发,可用于在更新前后进行一些操作。
<script>
import { beforeUpdate, afterUpdate } from 'svelte';
let count = 0;
beforeUpdate(() => {
// 在组件更新之前执行操作
console.log('组件将要更新');
});
afterUpdate(() => {
// 在组件更新之后执行操作
console.log('组件已更新');
});
function increment() {
count++;
}
</script>
<button on:click={increment}>增加</button>
<p>计数:{count}</p>
这里需要注意,组件初始化会触发第一次,后面点击后再次触发。
3. onDestroy
组件被销毁之前触发,可用于清理资源或取消订阅。
<script>
import { onDestroy } from "svelte";
// 初始化操作,比如开启一个定时器
const timer = setInterval(() => {
console.log("timer");
}, 1000);
onDestroy(() => {
// 组件销毁前执行清理操作,比如取消定时器
clearInterval(timer);
});
</script>
4. setContext 与 getContext
这是一对特殊的生命周期函数,将任意 context 对象与当前组件和指定的 key 关联并返回该对象和检索属于具有指定 key
的最近父组件的上下文。
可以用于同祖先的组件之间的数据传递,而不必像父向子传值一样一层一层传下去。必须在组件初始化期间调用它。这里很像Vue的provide和inject。
Parent.svelte:
<script>
import { setContext } from 'svelte';
import Child from './Child.svelte';
let message = 'Hello';
setContext('message', message);
</script>
<div>我是Parent,我传递了{message}</div>
<Child />
Child.svelte:
<script>
import Grandson from "./Grandson.svelte";
</script>
<div>我是Child</div>
<Grandson />
Grandson:
<script>
import { getContext } from "svelte";
let message = getContext("message");
</script>
<div>我是Grandson:我接受了{message}</div>
页面:
注意: 非同组先的组件,传递数据会失败。
比如Parent.svelte里面新增一个和Child.svelte同级的Brother.svelte组件,并从Child.svelte传递新的值test,Brother.svelte就接收不到。因为Child.svelte和Brother.svelte同级,它传递出来的数据只能由它的后代组件接收。
Brother.svelte:
<script>
import { getContext } from "svelte";
let message = getContext("message");
let test = getContext("test");
</script>
<div>我是Brother:我接受了{message}</div>
<div>我是Brother:我接受了{test}</div>
修改后的Child.svelte:
<script>
import Grandson from "./Grandson.svelte";
import { setContext } from "svelte";
let test = "非同祖先组件传递的数据";
setContext("message", test);
</script>
<div>我是Child,我传递了{test}</div>
<Grandson />
修改后的Parent.svelte:
<script>
import { setContext } from 'svelte';
import Child from './Child.svelte';
import Brother from './Brother.svelte';
let message = 'Hello';
setContext('message', message);
</script>
<div>我是Parent,我传递了{message}</div>
<Child />
<Brother />
页面:
6. hasContext
检查是否已在父组件的上下文中设置给定的 key
。必须在组件初始化期间调用。
<script>
import { hasContext } from 'svelte';
if (hasContext('message')) {
// do something
}
</script>
7. getAllContexts
检索属于最近父组件的整个上下文映射。必须在组件初始化期间调用。
<script>
import { getAllContexts } from 'svelte';
const contexts = getAllContexts();
</script>