网站 • API 文档 • 特性教程 • 在线演练场 • Discord
Solid 是一个用于创建用户界面的声明式 JavaScript 库。它不使用虚拟 DOM,而是将模板编译为真实的 DOM 节点,并通过细粒度的响应式更新它们。声明你的状态并在整个应用中使用它,当某个状态发生变化时,只有依赖于它的代码会重新运行。
概览
import { createSignal } from "solid-js";
import { render } from "solid-js/web";
function Counter() {
const [count, setCount] = createSignal(0);
const doubleCount = () => count() * 2;
console.log("函数体只运行一次...");
return (
<>
<button onClick={() => setCount(c => c + 1)}>
{doubleCount()}
</button>
</>
);
}
render(Counter, document.getElementById("app")!);
在我们的在线演练场中尝试这段代码!
解释一下!
import { createSignal } from "solid-js";
import { render } from "solid-js/web";
// 组件只是一个返回 DOM 节点的函数
function Counter() {
// 创建一个响应式状态,给我们一个访问器 count() 和一个设置器 setCount()
const [count, setCount] = createSignal(0);
// 要创建派生状态,只需将表达式包装在一个函数中
const doubleCount = () => count() * 2;
console.log("函数体只运行一次...");
// JSX 允许你在 JavaScript 函数中编写 HTML,并使用 { } 语法包含动态表达式
// 这里唯一会重新渲染的部分是 doubleCount() 文本。
return (
<>
<button onClick={() => setCount(c => c + 1)}>
递增:{doubleCount()}
</button>
</>
);
}
// render 函数将组件挂载到页面上
render(Counter, document.getElementById("app")!);
Solid 将你的 JSX 编译成高效的真实 DOM 更新。它在运行时使用相同的响应式原语(createSignal
),但确保尽可能少的重新渲染。以下是这个例子的编译结果:
import { template as _$template } from "solid-js/web";
import { delegateEvents as _$delegateEvents } from "solid-js/web";
import { insert as _$insert } from "solid-js/web";
// 编译器提取出任何静态 HTML
const _tmpl$ = /*#__PURE__*/_$template(`<button>递增:`);
import { createSignal, createEffect } from "solid-js";
import { render } from "solid-js/web";
function Counter() {
const [count, setCount] = createSignal(0);
const doubleCount = () => count() * 2;
console.log("函数体只运行一次...");
return (() => {
// _el$ 是一个真实的 DOM 节点!
const _el$ = _tmpl$();
_el$.$$click = () => setCount(c => c + 1);
// 这将 count 作为按钮的子元素插入,允许 count 更新而无需重新渲染整个按钮
_$insert(_el$, doubleCount);
return _el$;
})();
}
render(Counter, document.getElementById("app"));
_$delegateEvents(["click"]);
主要特性
- 对真实 DOM 进行细粒度更新
- 声明式数据:将你的状态建模为具有响应式原语的系统
- 一次性渲染的心智模型:你的组件是只运行一次来设置视图的常规 JavaScript 函数
- 自动依赖追踪:访问你的响应式状态会自动订阅它
- 体积小且速度快
- 简单:学习几个强大的概念,这些概念可以被重用、组合和构建
- 提供现代框架特性,如 JSX、片段、Context、Portals、Suspense、流式 SSR、渐进式水合、错误边界和并发渲染
- 天然可调试:
<div>
就是一个真实的 div,因此你可以使用浏览器的开发工具来检查渲染 - Web 组件友好,可以创作自定义元素
- 同构:在客户端和服务器上渲染你的组件
- 通用:编写自定义渲染器以在任何地方使用 Solid
- 不断增长的社区和生态系统,核心团队积极支持
快速开始
你可以通过在终端中运行以下命令来快速开始一个简单的应用:
> npx degit solidjs/templates/js my-app
> cd my-app
> npm i # 或 yarn 或 pnpm
> npm run dev # 或 yarn 或 pnpm
或者使用 TypeScript:
> npx degit solidjs/templates/ts my-app
> cd my-app
> npm i # 或 yarn 或 pnpm
> npm run dev # 或 yarn 或 pnpm
这将创建一个由 Vite 驱动的最小化、客户端渲染的应用程序。
或者你可以在自己的设置中安装依赖。要使用 Solid 和 JSX(推荐),运行:
> npm i -D babel-preset-solid
> npm i solid-js
最简单的设置方法是将 babel-preset-solid
添加到你的 .babelrc
、webpack 的 babel 配置或 rollup 配置中:
"presets": ["solid"]
对于 TypeScript,记得在你的 .tsconfig
中设置以处理 Solid 的 JSX:
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "solid-js",
}
为什么选择 Solid?
高性能
经过精心设计并拥有五年多的研究背景,Solid 的性能几乎与优化过的原生 JavaScript 无异(参见 JS Framework Benchmark 中的 Solid)。Solid 体积小且完全可树摇,在服务器渲染时也速度很快。无论你是编写完全客户端渲染的 SPA 还是服务器渲染的应用,你的用户都能比以往更快地看到它。(从库的创建者那里了解更多关于 Solid 性能的信息。)
强大
Solid 具备现代框架所应有的所有功能。内置的 Context 和 Store 提供高性能的状态管理:您无需使用第三方库来管理全局状态(如果不想的话)。通过 Resources,您可以像使用其他状态一样使用从服务器加载的数据,并借助 Suspense 和并发渲染为其构建响应式 UI。当您准备转向服务器端时,Solid 提供完整的 SSR 和无服务器支持,通过流式传输和渐进式水合作用尽快实现交互。(查看我们完整的交互功能演练。)
务实
用更少做更多:使用简单、可组合的原语,没有隐藏规则和陷阱。在 Solid 中,组件只是函数 - 渲染完全由状态的使用方式决定 - 因此您可以自由组织代码,无需学习新的渲染系统。Solid 鼓励声明式代码和读写分离等模式,有助于保持项目的可维护性,但又不会固执己见到妨碍您的程度。
高效
Solid 建立在 JSX 和 TypeScript 等成熟工具之上,并与 Vite 生态系统集成。Solid 的低级抽象让您可以直接访问 DOM,轻松使用喜欢的原生 JavaScript 库,如 D3。Solid 生态系统正在快速增长,包括自定义原语、组件库和构建时工具,让您能够以新方式编写 Solid 代码。
更多
浏览器支持
SolidJS Core 致力于支持过去 2 年的现代浏览器,包括 Firefox、Safari、Chrome 和 Edge(桌面和移动设备)。我们不支持 IE 或类似的过时浏览器。对于服务器环境,我们支持 Node LTS 以及最新的 Deno 和 Cloudflare Worker 运行时。
社区
来Discord与我们聊天吧!Solid 的创始人和其他核心团队成员都活跃在那里,我们一直在寻找贡献者。
贡献者
Open Collective
通过捐赠支持我们,帮助我们继续我们的活动。[贡献]
赞助商
成为赞助商,在我们的 GitHub README 上展示您的 logo 并链接到您的网站。[成为赞助商]