Svelte介绍
Svelte是前端一个框架,是由RollupJs的作者Rich Harris编写的编译型框架。主要特点:
- 用最基本的 HTML,CSS,Javascript 来写代码
- 直接编译成原生 JS,没有中间商(Virtual DOM) 赚差价
- 没有复杂的状态管理机制
实战 快速创建项目
- 下载模板的命令 npm init vite@latest
- 输入项目名
- 选择 Svelte 模板
- 进入项目并安装依赖 npm install
- 运行项目 npm run dev
- 在浏览器访问 http://127.0.0.1:5173/
运行结果:
如果想要查看编译后的代码可以安装插件vite-plugin-inspect
浏览器最后访问http://localhost:5173/__inspect/
即可看到编译后的代码
项目的结构
Svelte 基本语法
具体学习见官网www.svelte.cn/tutorial/ba… , 总的来说跟vue写法很类似
编译前后
以下面简单代码作为讲解
let name = "world",
a = "1";
function setName() {
name = "fesky";
}
function aa() {
a = "2";
}
</script>
<h1 on:click={setName}>Hello {name}{a}!</h1>
<h1 on:click={aa}>Hello {a}!</h1>
然后打开http://localhost:5173/__inspect/ 进行编译后源码查看
如图
let name = "world",
a = "1";
function setName() {
name = "fesky";
}
function aa() {
a = "2";
}
</script>
<h1 on:click={setName}>Hello {name}{a}!</h1>
<h1 on:click={aa}>Hello {a}!</h1>
会编译成如下,(相关不重要的代码删掉后)
import {
SvelteComponentDev,
add_location,
append_dev,
detach_dev,
dispatch_dev,
element,
init,
insert_dev,
listen_dev,
noop,
run_all,
safe_not_equal,
set_data_dev,
space,
text,
validate_slots
} from "svelte/internal";
const file = "src/App.svelte";
function create_fragment(ctx) {
let h10;
let t0;
let t1;
let t2;
let t3;
let t4;
let h11;
let t5;
let t6;
let t7;
let mounted;
let dispose;
const block = {
c: function create() {
h10 = element("h1");
t0 = text("Hello ");
t1 = text(/*name*/ ctx[0]);
t2 = text(/*a*/ ctx[1]);
t3 = text("!");
t4 = space();
h11 = element("h1");
t5 = text("Hello ");
t6 = text(/*a*/ ctx[1]);
t7 = text("!");
add_location(h10, file, 11, 0, 137);
add_location(h11, file, 12, 0, 182);
},
l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
},
m: function mount(target, anchor) {
insert_dev(target, h10, anchor);
append_dev(h10, t0);
append_dev(h10, t1);
append_dev(h10, t2);
append_dev(h10, t3);
insert_dev(target, t4, anchor);
insert_dev(target, h11, anchor);
append_dev(h11, t5);
append_dev(h11, t6);
append_dev(h11, t7);
if (!mounted) {
dispose = [
listen_dev(h10, "click", /*setName*/ ctx[2], false, false, false, false),
listen_dev(h11, "click", /*aa*/ ctx[3], false, false, false, false)
];
mounted = true;
}
},
p: function update(ctx, [dirty]) {
if (dirty & /*name*/ 1) set_data_dev(t1, /*name*/ ctx[0]);
if (dirty & /*a*/ 2) set_data_dev(t2, /*a*/ ctx[1]);
if (dirty & /*a*/ 2) set_data_dev(t6, /*a*/ ctx[1]);
},
i: noop,
o: noop,
d: function destroy(detaching) {
if (detaching) detach_dev(h10);
if (detaching) detach_dev(t4);
if (detaching) detach_dev(h11);
mounted = false;
run_all(dispose);
}
};
dispatch_dev("SvelteRegisterBlock", {
block,
id: create_fragment.name,
type: "component",
source: "",
ctx
});
return block;
}
function instance($$self, $$props, $$invalidate) {
let name = "world", a = "1";
function setName() {
$$invalidate(0, name = "fesky");
}
function aa() {
$$invalidate(1, a = "2");
}
return [name, a, setName, aa];
}
每个 Svelte 组件编译后都会有一个 create_fragment 方法,这个方法返回一些 DOM 节点的声明周期钩子方法,都是单个字母不好理解,从 源码 上可以看到每个缩写的含义。
interface Fragment {
key: string|null;
first: null;
/* create */ c: () => void;
/* claim */ l: (nodes: any) => void;
/* hydrate */ h: () => void;
/* mount */ m: (target: HTMLElement, anchor: any) => void;
/* update */ p: (ctx: any, dirty: any) => void;
/* measure */ r: () => void; /* fix */ f: () => void;
/* animate */ a: () => void; /* intro */ i: (local: any) => void;
/* outro */ o: (local: any) => void;
/* destroy */ d: (detaching: 0|1) => void; }
主要看以下四个钩子方法:
c(create) :在这个钩子里面创建 DOM 节点,创建完之后保存在每个 fragment 的闭包内。
m(mount) :挂载 DOM 节点到 target 上,在这里进行事件的板顶。
p(update) :组件数据发生变更时触发,在这个方法里面检查更新。
d(destroy) :移除挂载,取消事件绑定。
下期会具体介绍如何做到数据变更重新更新试图
项目落地
- 使用vite脚手架选择svelte模板生成项目
- 如果要在项目中使用less 则,安装pnpm i svelte-preprocess svelte-preprocess-less, 并且在vite.config.ts中配置如下
export default defineConfig({
plugins: [
Inspect(),
svelte({
preprocess: sveltePreprocess({
style: svelteLess(),
}),
}),],
})
3、使用ui组件库 svelte-material-ui 安装 npm install --save-dev @smui/各组件名字
例如:npm i -D @smui/button
引入: import Button, { Label } from '@smui/button';
4、路由 npm install --save svelte-routing
使用
<!-- App.svelte -->
<script>
import { Router, Link, Route } from "svelte-routing";
import Home from "./routes/Home.svelte";
import About from "./routes/About.svelte";
import Blog from "./routes/Blog.svelte";
export let url = "";
</script>
<Router url="{url}">
<nav>
<Link to="/">Home</Link>
<Link to="about">About</Link>
<Link to="blog">Blog</Link>
</nav>
<div>
<Route path="blog/:id" component="{BlogPost}" />
<Route path="blog" component="{Blog}" />
<Route path="about" component="{About}" />
<Route path="/"><Home /></Route>
</div>
</Router>
// main.js
import App from "./App.svelte";
const app = new App({
target: document.getElementById("app"),
hydrate: true
});
生态
- ssr -》 sapper git地址:github.com/sveltejs/sa…
- 组件库 - 》 svelte-material-ui git地址:github.com/hperrin/sve…
- Router -》 svelte-routing git地址:github.com/EmilTholin/…
- VScode 插件 marketplace.visualstudio.com/items?itemN…
- Native svelte-native
- 单元测试 svelte-testing-library
- Chrome Dev-tools Svelte Devtools
有什么优缺点
- 在相对大型的项目中,在项目中组件超过 15 个之后,Svelte 的整体的打包体积优势就已经几乎已不存在
Svelte的兼容性和周边生态相比起Vue和React会差一点- 不支持预处理器,比如说less/scss,需要自己单独的配置 webpack loader等