【SolidJs】仅次于原生JS的超级性能!SolidJs框架教程【上】(2)

简介: 背景今天被战友种草了一款前端框架,打开链接看文章,在各个指标的比较下,SolidJs脱颖而出,下面简单介绍一下这个框架,然后开始记录一下学习笔记。(Golang的事情暂时放一放,毕竟咱是专业前端「手动狗头」)。

onMount 生命周期

引用一段官方的话:

Solid 中只有少量的生命周期,因为一切的存活销毁都由响应系统控制。响应系统是同步创建和更新的,因此唯一的调度就是将逻辑写到更新结束的 Effect 中。

举个🌰

import { render } from "solid-js/web";
import { createSignal, onMount, For } from "solid-js";
function App() {
  const [photos, setPhotos] = createSignal([]);
  onMount(async () => {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/photos?_limit=20`
    );
    setPhotos(await res.json());
  });
  return (
    <>
      <h1>photos</h1>
      <div class="photos">
        <For each={photos()} fallback={<p>Loading</p>}>
          {(photo, i) => (
            <figure>
              <img src={photo.thumbnailUrl} alt={photo.title} />
              <figcaption>{photo.title}</figcaption>
            </figure>
          )}
        </For>
      </div>
    </>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

onCleanup

onCleanup函数可以执行一些销毁操作,举个栗子

import { render } from "solid-js/web";
import { createSignal, onCleanup } from "solid-js";
function Counter() {
  const [count, setCount] = createSignal(0);
  const timer = setInterval(() => setCount(count() + 1), 1000);
  onCleanup(() => clearInterval(timer));
  return <div>Count: {count()}</div>;
}
render(() => <Counter />, document.getElementById("app"));
复制代码

事件

在SolidJs中,事件均以on为前缀,举个🌰

import { render } from "solid-js/web";
import { createSignal } from "solid-js";
import "./style.css";
function App() {
  const [pos, setPos] = createSignal({ x: 0, y: 0 });
  function handleMouseMove(event) {
    setPos({
      x: event.clientX,
      y: event.clientY,
    });
  }
  return (
    <div onmousemove={handleMouseMove}>
      The mouse position is {pos().x} x {pos().y}
    </div>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

动态样式 Style

SolidJs中的style属性接受样式字符串和对象,但需要注意一点,官话:

对象形式不同于 Element.prototype.style,Solid 通过调用 style.setProperty 的封装来进行样式设置。

意味着样式的键需要采用中划线的方式,例如background-color而不是backgroundColor,但是这意味着可以设置CSS变量:

<div style={{'--my-custom-color': themeColor()}}></div>
复制代码

举个🌰

import { render } from "solid-js/web";
import { createSignal } from "solid-js";
function App() {
  const [num, setNum] = createSignal(0);
  setInterval(() => setNum((num() + 1) % 255), 30)
  return <div style={{
      color: `rgb(${num()}, 180, ${num()})`,
      'font-size': `${num()}px`
  }}>Some Text</div>;
}
render(() => <App />, document.getElementById('app'));
复制代码

动态类名 ClassList

SolidJs支持使用 classclassName设置元素的classname属性,classList用来设置多个class名,key是类名,value是一个boolean,举个🌰

function App() {
    const [current, setCurrent] = createSignal('foo')
    return <>
        <button class={current() === 'foo' ? 'selected' : ''} onClick={setCurrent('foo')}>foo</button>
        <button class={current() === 'bar' ? 'selected' : ''} onClick={setCurrent('bar')}>bar</button>
        <button class={current() === 'baz' ? 'selected' : ''} onClick={setCurrent('bar')}>baz</button>
    </>
}
复制代码

当然上面的代码也可以用classList,🌰:

<button classList={{'selected': current() === 'foo'}} onClick={setCurrent('foo')}>foo</button>
复制代码

Ref

SolidJs中,可以通过ref属性获取元素的引用,官话:

赋值行为是在元素创建时,在 DOM 被追加前发生的。 只需声明一个变量,元素引用就会赋值给该变量。

举个🌰

let myDiv;
<div ref={myDiv}>my Div</div>
复制代码

就可以了...

属性绑定/扩展

利用...扩展运算符,可以直接把属性传进子组件,举个🌰

main.tsx

import { render } from "solid-js/web";
import Info from "./info";
const pkg = {
  name: "dog",
  age: 3,
  gender: 0,
};
function App() {
  return <Info name={pkg.name} age={pkg.age} gender={pkg.gender}></Info>;
}
render(() => <App />, document.getElementById("app"));
复制代码

info.tsx

export default function Info(props) {
  console.log(props)
  return (
    <div>
      <p>name: {props.name}</p>
      <p>age: {props.age}</p>
      <p>gender: {props.gender === 0 ? "girl" : "boy"}</p>
    </div>
  );
}
复制代码

上面的main.tsx可以这样改造一下:

function App() {
  return <Info {...pkg}></Info>;
}
复制代码

是不是省了很多事儿!

指令

SolidJs可以通过use自定义指令,自定义指令仅仅只是一个形式为(element, valueAccesor)的函数,其中valueAccesor是一个获取绑定值的函数,只要函数是在作用域中导入的,就可以通过use:使用。

重要提示:use: 需要被编译器检测并进行转换,并且函数需要在作用域内,因此不能作为传值的一部分或在组件上使用。

举一个modal的🌰:

main.tsx

import { render } from "solid-js/web";
import { createSignal, Show } from "solid-js";
import clickOutside from './click-outside'
function App() {
    const [show, setShow] = createSignal(false)
    return (
        <Show when={show()} fallback={<button onClick={setShow(true)}>show Modal</button>}>
            <div class="modal" use:clickOutside={show(false)}>modal box</modal>
        </Show>
    )
}
render(() => <App />, document.getElementById("app"));
复制代码

click-outside.tsx

import { onCleanup } from 'solid-js';
export default function clickOutside(el, accessor) {
    const onClick = (e) => !el.contains(e.target) && accessor()?.();
    document.body.addEventListener('click', onClick)
    onCleanup(() => document.removeEventListener('click', onClick))
}
复制代码

props

SolidJs中的props传值上面已经有🌰了,很简单,再举个🌰

main.tsx

import WelcomeWord from './welcomeWord'
function App() {
    reutrn (
        <>
            <WelcomeWord gretting="Hi" name="Bob"></WelcomeWord>
        </>
    )
}
复制代码

welcomeWord.tsx

export default function welcomeWord(props) {
    return <h1>{props.gretting || 'hello'} {props.name || 'Alice'}</h1>
}
复制代码

props赋值默认值通过mergeProps操作,上面的🌰就可以改成这样

welcomeWord.tsx

import { mergeProps } from 'solid-js'
export default function welcomeWord(props) {
    const merged = mergeProps({ greeting: 'hello', name: 'Alice' }, props)
    return <h1>{merged.greeting} {merged.name} </h1>
}
复制代码

就很完美,官话:

Solid 有一些工具函数可以帮助我们处理 props。 第一个 mergeProps 函数听起来很像它名字描述得那样合并 props。mergeProps 将潜在的响应式对象合并而不会失去响应式性。最常见的情况就是是为组件设置默认 props。

props分离

在SolidJs中解构一个props会失去数据的响应性,可以通过splitProps来分离一个props,举个🌰

main.tsx

import { render } from "solid-js/web";
import { createSignal } from "solid-js";
import Greeting from "./greeting";
function app() {
    const [name, setName] = createSignal("Jack")
    return <>
        <Greeting greeting="Yo" name={name()} style="color: teal;" />
        <button onClick={setName("Alice")}>set name</button>
    </>
}
render(() => <App />, document.getElementById('app'));
复制代码

greeting.tsx

export default function Greeting(props) {
    let { greeting, name, ...others } = props
    return <h3 {...others}>{greeting} {name}</h3>
}
复制代码

这种方式修改name的时候,发现子组件并没有修改,所以需要使用splitProps

import { splitProps } from "solid-js";
export default function Greeting(props) {
  const [local, others] = splitProps(props, ["greeting", "name", "age"]);
  console.log(local, others)
  return (
    <h3 {...others}>
      {local.greeting} {local.name} {local.age}
    </h3>
  );
}
复制代码

就很完美!

目录
相关文章
|
17天前
|
前端开发 JavaScript Java
JavaScript闭包深入剖析:性能剖析与优化技巧
JavaScript 闭包是强大而灵活的特性,广泛应用于数据封装、函数柯里化和事件处理等场景。闭包通过保存外部作用域的变量,实现了私有变量和方法的创建,提升了代码的安全性和可维护性。然而,闭包也可能带来性能问题,如内存泄漏和执行效率下降。为优化闭包性能,建议采取以下策略:及时解除对不再使用的闭包变量的引用,减少闭包的创建次数,使用 WeakMap 管理弱引用,以及优化闭包结构以减少作用域链查找的开销。在实际开发中,无论是 Web 前端还是 Node.js 后端,这些优化措施都能显著提升程序的性能和稳定性。
111 70
|
3月前
|
监控 JavaScript 算法
如何使用内存监控工具来定位和解决Node.js应用中的性能问题?
总之,利用内存监控工具结合代码分析和业务理解,能够逐步定位和解决 Node.js 应用中的性能问题,提高应用的运行效率和稳定性。需要耐心和细致地进行排查和优化,不断提升应用的性能表现。
224 77
|
28天前
|
JavaScript 前端开发 测试技术
盘点原生JavaScript中直接触发事件的方式
本文全面探讨了原生JavaScript中触发事件的多种方式,包括`dispatchEvent`、`Event`构造函数、`CustomEvent`构造器、直接调用事件处理器以及过时的`createEvent`和`initEvent`方法。通过技术案例分析,如模拟点击事件、派发自定义数据加载事件和实现提示框系统,帮助开发者掌握这些方法在实际开发中的应用,提升灵活性与兼容性。
35 3
|
3月前
|
存储 缓存 JavaScript
如何优化Node.js应用的内存使用以提高性能?
通过以上多种方法的综合运用,可以有效地优化 Node.js 应用的内存使用,提高性能,提升用户体验。同时,不断关注内存管理的最新技术和最佳实践,持续改进应用的性能表现。
171 62
|
2月前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
548 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
3月前
|
存储 缓存 监控
如何使用内存监控工具来优化 Node.js 应用的性能
需要注意的是,不同的内存监控工具可能具有不同的功能和特点,在使用时需要根据具体工具的要求和操作指南进行正确使用和分析。
91 31
|
3月前
|
Web App开发 JavaScript 前端开发
2024年5月node.js安装(winmac系统)保姆级教程
本篇博客为2024年5月版Node.js安装教程,适用于Windows和Mac系统。作者是一名熟悉JavaScript与Vue的大一学生,分享了Node.js的基本介绍、下载链接及简单安装步骤。安装完成后,通过终端命令`node -v`验证版本即可确认安装成功。欢迎关注作者,获取更多技术文章。
51 2
2024年5月node.js安装(winmac系统)保姆级教程
|
2月前
|
JSON 缓存 负载均衡
Node.js 的性能
Node.js 的性能
96 12
|
3月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
3月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
66 2

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    47
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    Node.js 中实现多任务下载的并发控制策略
    34
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 5
    【JavaScript】深入理解 let、var 和 const
    49
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    47
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    57
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    57
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    57