十分钟掌握使用 SolidJS 构建全栈 CRUD 应用程序
我们可以开始讨论 SolidJS
,说它比React
更好,但没有必要做这种比较。SolidJS
只是众多前端框架之一,旨在在Web
上快速创建数据驱动。那么,我们为什么要突出这个新孩子呢?
首先,我们不能忽视SolidJS
不使用虚拟DOM。是的,你没听错!SolidJS
不使用虚拟 DOM,而是从应用程序第一次运行开始就记住整个 DOM,然后在有更新时,它会继续更新该部分。此功能使框架非常快速和高性能。
在本文中,我们将介绍如何构建一个简单的 CRUD
应用程序来演示 SolidJS
的有效性。
构建 SolidJS 前端
为了构建我们的 Solid 应用程序,我们将使用 Solid JD App
库[https://github.com/OrJDev/create-jd-app]。我们将设置项目,然后创建并渲染 SolidJS
组件。
安装Solid JD 应用程序库
要开始使用,请在终端上运行以下命令:
npm create jd-app@latest
系统将提示你键入 y(表示是)以继续,然后系统会要求你提供应用的名称。接下来,系统会询问您是否将使用 Vercel 来部署项目。这是一个偏好问题。您决定在哪里部署或托管项目完全取决于您;您甚至可以选择“无”作为选项。
我们使用的库还附带了额外的可选附加组件(AuthJS
,Prisma
,tRPC
,pRPC
,TailwindCSS
,AuthJS
和Upstash Ratelimit
)。您可以决定选择所需的内容或忽略它们。在本教程中,我们将通过仪表板部署到 Vercel,我们不会使用任何可选的附加组件:
做出选择后,单击 Enter。这将立即安装您需要的所有内容,包括包含 SolidJS 依赖的其他软件包的 node_modules 文件夹,以及您在安装过程中选择的任何软件包。
设置项目
在本教程中,我们将构建一个简单的博客应用。移动到托管应用程序的根目录,然后运行以下命令:
npm run dev
这将在端口 3000 上启动应用程序;http://localhost:3000,您将在这里看到它。
您的代码库将如下所示;注意 TypeScript 的使用:
以下是您将在浏览器中看到的内容:
接下来,清除 src/route/index.tsx
文件中的现有代码并粘贴以下内容:
import "../assets/css/style.css";
import { type VoidComponent } from "solid-js";
import { A } from "solid-start";
import Blog from '../components/Blog'
const Home: VoidComponent = () => {return (<main><div class="container"><div class="row g-4"><div class="col-lg-8"><div class="bg-mode p-4"><h1 class="h4 mb-4">Latest blogs</h1></div></div></div></div></main>);
};
export default Home;
创建 SolidJS 组件
组件是前端框架最好的东西之一,尽管组件的概念并不新鲜。组件只是一组一个或多个 HTML 元素,但它们使我们更容易动态管理和复用元素。
请在 src
名为 components
的目录下开始制作组件;我们将在此处放置任何可重用的元素和文件。在 components
文件夹中,创建一个名为 Blog.jsx
并粘贴以下代码的文件:
import solidimage from '../assets/images/solid.jpg'
function Blog() {return (<><div class="card bg-transparent border-0"><div class="row g-3"><div class="col-4"><img class="rounded" src={solidimage} alt="" /></div><div class="col-8"><ahref="#"class="badge bg-danger bg-opacity-10 text-danger mb-2 fw-bold">Tech</a><h5><ahref="blog-details.html"class="btn-link stretched-link text-reset fw-bold">What is Solidjs? </a></h5><div class="d-none d-sm-inline-block"><p class="mb-2">SolidJS is an exciting framework for web development that has been gaining traction in recent years. It has been created by Misko Hevery, the creator of Angular.
.</p><a class="small text-secondary" href="#!">{" "}<i class="bi bi-calendar-date pe-1"></i> Jan 22, 2022</a></div></div></div></div><hr class="my-4" /></>);
}
export default Blog;
您还需要下载图像并在 src
该文件夹中创建子文件夹assets/images
的文件。
接下来,assets/css
在子文件夹中创建一个 style.css
文件并添加此代码。此代码中的 CSS
是 Bootstrap
。
渲染 SolidJS 组件
您可能会遇到问题,就像我一样,渲染SolidJS
组件。如果是这样,最简单的解决方案是在位于项目根目录的 tsconfig.json
文件中添加以下内容:
"noImplicitAny": false
我们将在src/route
文件夹中的文件内 index.tsx
渲染 SolidJS
组件,如下所示:
import "../assets/css/style.css";
import { type VoidComponent } from "solid-js";
import { A } from "solid-start";
import Blog from '../components/Blog'
const Home: VoidComponent = () => {return (<main><div class="container"><div class="row g-4"><div class="col-lg-8"><div class="bg-mode p-4"><h1 class="h4 mb-4">Latest blogs</h1><Blog /><Blog/><Blog/></div></div></div></div></main>);
};
export default Home;
唯一的区别是,在第 4 行,我们导入了三次 Blog 组件。以下是我们现在在 Web 浏览器中看到的内容:
在后端创建动态渲染
我们刚刚在上一节中创建的是静态数据。但是,在现实世界中,数据将来自某种后端或API。所以,让我们让事情变得动态!
首先,我们需要有某种端点。在本教程中,我们将使用以下终结点 https://crudcrud.com/api/6a1613c7646f4a908158592cfdb448aa/blog,其中包含博客列表:
要在 Blog 组件中动态呈现来自 API 的数据,请更新Blog.jsx
文件,如下所示:
import { For, createResource } from "solid-js";
import solidimage from "../assets/images/solid.jpg";
const getBlogs = async () => {const response = await fetch("https://crudcrud.com/api/6a1613c7646f4a908158592cfdb448aa/blog");return response.json();
};
function Blog() {const [blog] = createResource(getBlogs);return (<Show when={blog()}><For each={blog()}>{(eachblog) => (<><div class="card bg-transparent border-0"><div class="row g-3"><div class="col-4"><img class="rounded" src={solidimage} alt="" /></div><div class="col-8"><ahref="#"class="badge bg-danger bg-opacity-10 text-danger mb-2 fw-bold">{eachblog.tag}</a><h5><ahref="blog-details.html"class="btn-link stretched-link text-reset fw-bold">{eachblog.title}</a></h5><div class="d-none d-sm-inline-block"><p class="mb-2">{eachblog.text}</p><a class="small text-secondary" href="#!">{" "}<i class="bi bi-calendar-date pe-1"></i> Jan 22, 2022</a></div></div></div></div><hr class="my-4" /></>)}</For></Show>);
}
export default Blog;
在这里,我们导入来自SolidJS
的 <For/>
组件。此组件用于遍历 API 的内容(第 13 行和第 49 行)。
我们还导入了一个 SolidJS CreateResource
方法。这用于保存我们从 fetch
响应中获取的 JSON
响应(第 10 行)的内容(请参阅第 3-8 行)。
SolidJS
还为我们提供了另一个组件,<Show/>
它可以帮助我们有条件地渲染东西。我们用来 <Show/>
包装整个 Blog 组件的内容。
该 <Show/>
组件提供了一个 when()
方法,这是我们实际定义条件的地方。我们指定 <Show/>
组件仅在存在数据或变量时有内容时呈现(请参阅第 12 行)。
以下是浏览器的外观:
设置路由
路由是指我们如何从资源的一条路径移动到另一条路径。与其他现代Web技术类似,SolidJS
使用Solid Router
来管理客户端请求的处理方式以及处理请求的内容。固态路由器简单明了。
在撰写本文时,默认情况下未安装Solid Router
包。但是,我们使用Solid JD App
库来设置我们的项目,该库包括路由器。
要设置路由,请创建一个新组件 , BlogDetail.jsx
其中将显示博客正文。然后,粘贴以下代码:
import { useParams } from "@solidjs/router"
import { createResource } from "solid-js"
const getBlog = async (_id) => {const response = await fetch('https://crudcrud.com/api/64b773f6659a41b69d678369943f3c5f/blog/' + _id)return response.json()
}
export default function BlogDetail() {const params = useParams();const [blogdetail] = createResource(params._id, getBlog);console.log(blogdetail);return (<div class="my-7"><Show when={blogdetail()}><div class=""><div class=""><h2 class="">{blogdetail.title}</h2><h2>{blogdetail.body}</h2></div></div>tun</Show></div>)
}
查看 API 响应,您会注意到有一个 _id
唯一的字段;这就是我们将用来定位每条内容的内容。
在此代码中,我们导入 useParams
(第 1 行),该行用于从 URL 定位特定参数。然后,我们使用其唯一 _id
作为路径参数获取每篇博客文章,并以 JSON 形式返回(参见第 3-6 行)。
接下来,我们导出( BlogDetail
第 13-24 行)并在 params
变量(第 8 行)中启动 useParams()
,该变量用作CreateResource()
方法中的参数(第 9 行)。然后,我们返回博客的title and body
内容(第 11-23 行)。
现在,我们需要在 src/route/index.tsx
文件中定义此路由。更新代码,如下所示:
import "../assets/css/style.css";
import { type VoidComponent } from "solid-js";
import { A, Router, Route, Routes } from "@solidjs/router";
import Blog from '../components/Blog';
import BlogDetail from '../components/BlogDetail';const Home: VoidComponent = () => {return (<main><div class="container"><div class="row g-4"><div class="col-lg-8"><div class="bg-mode p-4"><h1 class="h4 mb-4">Latest blogs</h1><Blog /></div></div></div></div><Router><Routes><Route path='/blog/:_id' component={BlogDetail}/> </Routes></Router></main>);
};
export default Home;
这里的更改是我们从 solidjs/router
包中导入了<Router/>
、 组件<Routes/> <Route/>
(第 3 行)并使用它们来收集数据(第 20-24 行)。如果您仔细查看第 22 行,您会发现我们定义了尝试访问博客文章路径参数 /blog/_id
.由于这必须是动态的,因此我们传递了组件以返回BlogDetail
.
总结
在本文中,我们成功地演示了如何使用 SolidJS
构建博客。您可以将这些知识扩展到其他类型的应用程序。我们查看了一些 SolidJS
方法和组件,并研究了它们如何在项目中使用。
SolidJS
的一个杀手级特性是它在第一次加载时记住虚拟 DOM,随后,不同的部分将根据需要更新,而不会影响整个 DOM。
我希望你喜欢这篇文章。该项目的完整代码库可以在GitHub[https://github.com/bigpreshy/solid-crud]上访问。您可能还需要查看此部署:https://solid-crud-ten.vercel.app/。
相关文章:

十分钟掌握使用 SolidJS 构建全栈 CRUD 应用程序
我们可以开始讨论 SolidJS,说它比React更好,但没有必要做这种比较。SolidJS只是众多前端框架之一,旨在在Web上快速创建数据驱动。那么,我们为什么要突出这个新孩子呢? 首先,我们不能忽视SolidJS不使用虚拟…...

LabVIEW开发多材料摩擦电测量控制系统
LabVIEW开发多材料摩擦电测量控制系统 摩擦电效应是两个物体摩擦在一起,电荷从一个物体转移到另一个物体的现象,从而导致两个物体携带相等和相反的电荷。接触和充电是主导该过程的两个关键因素。当静电荷累积到一定水平时,可能会出现放电现象…...

【Linux】网络基础1
文章目录 网络基础11. 计算机网络背景1.1 网络发展 2. 认识协议2.1 网络协议2.2 OSI七层模型2.3 TCP/IP五层(或四层)模型 3. 网络传输基本流程3. 1 数据报封装和分用 4. 网络中的地址管理4.1 认识IP地址 5. 认识MAC地址 网络基础1 1. 计算机网络背景 1…...
HTML - Javascript - 原生的JS HTTP请求:实用主义的一篇文章
HTML - Javascript - 原生的JS HTTP请求:实用主义的一篇文章 前言 虽然现在使用JQuery等可以做到很方便的HTTP请求,但是这样做毕竟要引入一些JS文件。 如果想使用原生的JS进行HTTP网络请求应该怎样呢?可以使用XMLHttpRequest。 使用方法 …...

Intellij IDEA运行报Command line is too long的解决办法
想哭,vue前端运行起来,对应的后端也得起服务。 后端出的这个bug,下面的博客写的第二种方法,完整截图是下面这个。 Intellij IDEA运行报Command line is too long的解决办法 - 知乎 (zh…...
信号槽传输过程中指针所指对象的生命周期
在子线程中的一个槽函数,当读取到dxf文件完成后,结果通过在该槽函数中的 dx_data* pDxfData 指针变量读取。 然后通过QVariant封装该指针变量。发送到主线程中。 void qcWorker::slotReadDxfFile(QString dir) {bool bRtn{ false }; //定义一个局部指针…...
c++ 递归锁的使用
非递归锁 同一个线程里,在锁未释放的情况下反复加锁,会导致死锁。 示例 #include <iostream> #include <mutex> #include <thread> #include <unistd.h> using namespace std;std::mutex m_mutex;void Func() {m_mutex.lock(…...
Oracle TDE wallet
1. 钱夹密码千万不能忘记,这也是使用TDE 需要承担的风险。 2. 只要将wallet cwallet.sso 拷贝过去,加密没有意义! 钱夹的备份 正如上述,已经加密过的表列或者表空间,钱夹必须打开才能够查询到里面的数据。如果钱夹丢…...

多模态学习
一、目标 三、多模态核心任务 题目:...

Android学习之路(2) 文本设置
Android学习之路(1) 文本 一、设置文本内容 设置文本内容的两种方式: 一种是在XML文件中通过属性android:text设置文本代码如下 <TextViewandroid:id"id/tv_hello"android:layout_width"wrap_content"android:layout_height"wrap_c…...

手写springboot
前言 首先确定springboot在spring基础上主要做了哪些改动:内嵌tomcatspi技术动态加载 一、基本实现 1. 建一个工程目录结构如下: springboot: 源码实现逻辑 user : 业务系统2.springboot工程项目构建 1. pom依赖如下 <dependencies>…...

报错Uncaught (in promise) Error: Manifest request to...
在使用nuxt框架时,出现如下报错: 解决方案: 不要打开两个以上的开发者工具更换nuxt的端口号 参考资料:https://github.com/nuxt/nuxt.js/issues/6202...

微信私域更好玩了
之前分享过,“小绿书”“公众号文章转音频”等内测中或悄悄已升级的功能。 其实,微信还在内测很多新功能,只是没公开 今天,小编又发现新升级 就是『附近』功能 增加了一个本地生活的入口,这里面是短视频和图文 展示…...
基于ant-design的a-modal自定义vue拖拽指令
写一个dragDialog.js 在main.js中引入 import ‘./core/directives/dragDialog.js’ // 让 dialog 支持鼠标拖动 import Vue from vueVue.directive(DragDialog, {update: function (el, binding, vnode) {if (!binding.value || !binding.value.reset) returnconst dialog e…...
【ES】笔记-模板字符串(template string)是增强版的字符串`${expresions}`
模板字符串 传统的 JavaScript 语言,输出模板通常是这样写的(下面使用了 jQuery 的方法)。 $(#result).append(There are <b> basket.count </b> items in your basket, <em> basket.onSale </em> are on sal…...

利用 OLE 对象漏洞的 HWP 恶意文件浮出水面
ASEC 分析人员发现了一个利用 OLE 对象的恶意 HWP 文件,尽管其使用了 2020 年就被识别的恶意 URL,但仍然使用了 Flash 漏洞(CVE-2018-15982),需要用户谨慎对待。 打开 HWP 文件时会在 %TEMP%文件夹中生成如下文件。攻…...

【CSS】倾斜按钮
效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"/><meta http-equiv"X-UA-Compatible" content"IEedge"/><meta name"viewport" content"widthdevice-…...

js 正则表达式
js 正则表达式 http://tool.oschina.net/regex https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions 11 22...

心理咨询预约管理系统javaweb医院挂号jsp源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 心理咨询预约管理系统javaweb MVC模式,普…...

Linux中安装Node
安装 先从 官方网站 下载安装包,有时 node 版本太新会导致失败,详见下方的常见问题第2点 cd /home // 创建目录,将下载好的 node 安装包上传到此目录 mkdir Download mkdir /usr/local/lib/node解压 // 解压,前面是文件当前路径…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...