前言
Solid.js,一个比 React 更 react 的框架。每一个使用 React 的同学,你可以不使用,但不应该不了解。
目前 Solid.js 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Solid.js,为爱发电翻译文档。
我同时搭建了 Solid.js 最新的中文文档站点:solid.yayujs.com ,欢迎勘误。
虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。
欢迎围观朋友圈、加入低调务实优秀中国好青年前端社群,一个人走得快,一群人走得远。
Refs
Refs 是可以附加到任何元素的特殊属性,用于引用 DOM 元素或组件实例。当您需要直接访问 DOM 节点或调用组件上的方法时,它们特别有用。
访问 DOM 元素
访问 DOM 元素的一种方法是通过元素选择器,例如 document.querySelector 或 document.getElementById 。由于 Solid 中的元素可以根据状态添加到 DOM 或从 DOM 中删除,因此您需要等到该元素挂载到 DOM 后才能访问它。这可以通过使用 onMount 等待元素挂载到 DOM 后再访问它来完成。
因此,不建议通过元素选择器访问 DOM 元素。当在 DOM 中添加和删除具有相同选择器的元素时,将返回与选择器匹配的第一个元素,该元素可能不是您想要的元素。
JSX 作为一个值
当想要直接访问 DOM 元素时,JSX 可以用作值并分配给变量。
tsx
function Component() {
const myElement = <p>My Element</p>
return <div>{myElement}</div>
}
这使您可以创建和访问类似于 document.createElement 的 DOM 元素,但不必等到它挂载到 DOM。它可以多次使用,而不必担心重复的选择器。
这种方法的缺点是它将元素和任何子元素与 JSX 结构的其余部分分开。这使得组件的 JSX 结构更难以阅读和理解。
Solid 中的 Refs
Solid 提供了一个引用系统直接在 JSX 模板内访问 DOM 元素,从而保持元素结构的完整性。
要使用 ref ,您需要声明一个变量并将其用作 ref 属性:
jsx
function Component() {
let myElement;
return (
<div>
<p ref={myElement}>My Element</p>
</div>
)
}
这些赋值发生在创建时,在将元素添加到 DOM 之前。
如果在将元素添加到 DOM 之前需要访问该元素,可以使用 ref 的回调形式:
jsx
<p ref={(el) => {
myElement = el // 被创建但还没有添加到 DOM
}}>
My Element
</p>
说明
在 TypeScript 中,您必须使用明确的赋值断言。由于 Solid 在渲染组件时负责分配变量,因此这会向 TypeScript 发出信号,表明该变量将被分配,即使它无法确认。
jsx
let myElement!: HTMLDivElement;
Signals 作为 refs
信号也可以用作 refs。当您想要直接访问元素,但该元素在组件首次渲染时可能不存在,或者可能在某个时刻从 DOM 中删除时,这很有用。
jsx
function App() {
const [show, setShow] = createSignal(false)
const [element, setElement] = createSignal()
return (
<div>
<button onClick={() => setShow((isShown) => !isShown)}>Toggle</button>
<Show when={show()}>
<p ref={setElement}>This is the ref element</p>
</Show>
</div>
)
}
在这个例子中,仅当 show
信号为 true
时才会渲染段落元素。组件初始化时,段落元素不存在,因此 element
变量未赋值。一旦 show
信号设置为 true
,就会渲染段落元素,并将 element
变量分配给段落元素。
您可以在 Solid Playground 示例中更具体的查看 ref 更新生命周期。
转发 refs
转发 refs 是一种允许您将 ref 从父组件传递到子组件的技术。当您想要从父组件访问子组件的 DOM 元素时,这非常有用。
要转发 ref,您需要将 ref 传递给子组件,然后将 ref 分配给子组件的元素。
当子组件从其父组件接收到 ref
属性时,ref 将作为回调函数传递。这与父级是将其作为简单赋值还是回调传递无关。
一旦子组件收到 ref ,就可以通过 ref 属性将其分配给子组件想要公开的元素。要访问子组件中的 ref,请将其作为 prop 传递:
jsx
// Parent component
import { Canvas } from "./Canvas.jsx"
function ParentComponent() {
let canvasRef
const animateCanvas = () => {
// Manipulate the canvas using canvasRef...
}
return (
<div>
<Canvas ref={canvasRef} />
<button onClick={animateCanvas}>Animate Canvas</button>
</div>
)
}
// Child component
function Canvas(props) {
return (
<div className="canvas-container">
<canvas ref={props.ref} /> {/* Assign the ref to the canvas element */}
</div>
)
}
在这个例子中,通过 props.ref
变量直接为 canvas
元素分配 ref
属性。这会将 ref 转发到父组件,使其可以直接访问 canvas 元素。
指令(Directives)
指令允许将可复用行为附加到 DOM 元素。 use:
前缀用于表示这些自定义指令。与 props 或 attribute 不同,指令通过对其附加的元素提供细粒度的控制来在较低级别上运行。
指令类似于回调引用,但它们支持两个额外的功能:
- 一个元素上有多个指令。
- 将响应式数据传递给回调。
指令本质上是一个具有特定签名的函数:
typescript
function directive(element: Element, accessor: () => any): void
element
: 应用指令的 DOM 元素。accessor
: 一个可以访问传递给指令的值的函数。
指令函数在渲染时调用,但在元素添加到 DOM 之前调用。由于这个顺序,元素可以完全准备好它们的特性、属性或事件监听器,从而最大限度地减少意外行为或过早的交互。
在指令中,您可以执行各种任务,包括:
要了解更多有关指令及其如何与 TypeScript 配合使用的信息,请参阅我们的 TypeScript for Solid 指南 。
系列文章
本篇已收录在掘金专栏 《Solid.js 中文文档》。
此外我还写过 React 系列、TypeScript 系列、Next.js 系列、VuePress 博客搭建系列、JavaScript 系列等多个系列文章,全系列文章目录:github.com/mqyqingfeng...
通过文字建立交流本身就是一种缘分,欢迎围观朋友圈、加入低调务实优秀中国好青年前端社群,一个人走得快,一群人走得远。