Svelte 5 中的'助手”变量
再见神奇 Svelte 4 $:
在我最近发布 Svelte 5 迁移的经验和注意事项之后,我想重点介绍从 Svelte 4 迁移到 Svelte 5 时的一些技巧和心态的变化。
Svelte 4 使用“神奇的”$: 并让和完成所有繁重的工作以使代码具有反应性。我们还接受了变量重新分配,例如
<script> let arr = [1, 2, 3] let value = 4 arr = [...arr, value] </script>
而不是更新/改变变量的方法,如推送等
我很惊讶能够使用 Svelte 5 重新学习好的旧 JS 模式。
无需一直保持反应
而且我也可能被 Svelte 4 中的 let 宠坏了,没有考虑反应性,如果需要的话它会被包含在内。 但并非所有变量都必须是反应性的。非反应性变量也可以在反应性甚至“传统变异代码”中更新。反应式变量的真正需要是当我们在 UI 中使用它时(当这个变量在 html/页面中呈现并且我们需要它稍后更新时)。
您可能会在 Svelte 5 中遇到错误,例如无法分配给派生状态,在其自己的范围内引用的状态永远不会更新。您的意思是在闭包内引用它吗?或衍生_引用_selfn如果使用 Svelte 4 编码风格,则派生值无法递归引用自身。
辅助变量的示例
看一下这个 Svelte 4 风格的代码示例:
<script> let value; let derivedArr = [] $: if (value) { derivedArr = [...derivedArr, value] } function random () { value = Math.floor(1 + Math.random() * 10) } </script> <button on:click="{random}">Generate Random Value</button> <p>value: {value}</p> <p>derivedArr: {derivedArr}</p>
演示
我们有两个反应变量,Svelte 4 会自动解决更新问题。我们只需要记住正确的方法是重新分配变量。
在 Svelte 5 中,我们应该思考如何实现相同的结果。我们使用的两个变量还不够,我们还需要一个,即辅助变量。
首选方法是使用 $driven() 符文。
<script> let value = $state(); let helperArr = []; let derivedArr = $derived.by(() => { if (value) { helperArr.push(value); return helperArr; } }); function random () { value = Math.floor(1 + Math.random() * 10) } </script> <button onclick="{random}">Generate Random Value</button> <p>value: {value}</p> <p>derivedArr: {derivedArr}</p>
演示
如果您知道更简单的方法,请告诉我。
还有一个 $effect() 符文方法可以实现相同的效果。它可能看起来更简单,但我们应该尽可能避免效果(主要是 Svetlet 5 效果不在服务器/SSR 上运行)。
<script> let value = $state(); let helperArr = [] let effectArr = $derived(helperArr); $effect.pre(() => { if (value) { helperArr.push(value) } }) function random () { value = Math.floor(1 + Math.random() * 10) } </script> <button onclick="{random}">Generate Random Value</button> <p>value: {value}</p> <p>effectArr: {effectArr}</p>
演示
现实生活中的例子
这是我尝试将 Svelte 4 页面直接迁移到 Svelte 5 的示例。我花了一段时间重新思考代码。此页面用作帖子搜索,具有“加载更多”功能(如果用户没有 JS,则添加结果或分页):
苗条4
从 '../components/Icon.svelte' 导入图标; 从'$app/forms'导入{增强}; 从'svelte'导入{tick}; 出口许可证表格; 导出让搜索语言; 导出让l; 让结果= []; 让以前的搜索=''; 让搜索项; 让我们跳过; $: if (!!form && form?.thereIsMore) { searchTerm = form.searchTerm; 跳过=数字(形式?.跳过)20; } $: if (!!form?.searchResultFromAction) { if (previousSearch == form.searchTerm && form.thereWasMore) { 结果= [...结果,...form.searchResultFromAction]; } 别的 { 结果= [...form.searchResultFromAction]; previousSearch = form.searchTerm; } } 异步函数 intoView(el) { 等待刻度线(); if (el.attributes.index.nodeValue == 跳过 - 20 && 跳过!= 未定义) { el.scrollIntoView({ 行为: '平滑' }); } } 脚本> {#if 结果.length} <ol> {#每个结果作为项目,索引} <li use:intoview aria-posinset="{index}"> <!-- 没有 javascript 的用户已经计算了分页中的结果顺序,并且 css 禁用了标准 ol ul 编号 --> <!-- 使用 javascript 的用户具有标准的 ol ul 编号和加载更多功能 --> <noscript>{数字(索引)1 数字(形式?.skip)}。 无脚本> <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a> </noscript> </li> {/每个} </ol> {#if 形式?.thereIsMore} <!-- 可能我们不需要绑定该值,因为这是隐藏输入 --> <!-- <input name="searchTerm" type="hidden" bind:value={searchTerm} /> --> 标签> <button aria-label="加载更多搜索结果的按钮"> <p>苗条5<br> </p> <pre class="brush:php;toolbar:false"> 从 '../components/Icon.svelte' 导入图标; 从'$app/forms'导入{增强}; 从'svelte'导入{tick}; let { form, searchLang, l } = $props(); 让以前的搜索=''; 让skip = $衍生.by(() => { if (!!form && form?.thereIsMore) { 返回 Number(form?.skip) 20; } }); 让helperResultsArr = []; 让结果= $衍生.by(() => { if (!!form?.searchResultFromAction) { if (previousSearch == form.searchTerm && form.thereWasMore) { helperResultsArr.push(...form.searchResultFromAction); 返回helperResultsArr; } 别的 { helperResultsArr = []; helperResultsArr.push(...form.searchResultFromAction); previousSearch = form.searchTerm; 返回helperResultsArr; } 否则返回[]; }); 异步函数 intoView(el) { 等待刻度线(); if (el.attributes.index.nodeValue == 跳过 - 20 && 跳过!= 未定义) { el.scrollIntoView({ 行为: '平滑' }); } } 脚本> {#if 结果.length} <ol> {#每个结果作为项目,索引} <li use:intoview aria-posinset="{index}"> <!-- 没有 javascript 的用户已经计算了分页中的结果顺序,并且 css 禁用了标准 ol ul 编号 --> <!-- 使用 javascript 的用户具有标准的 ol ul 编号和加载更多功能 --> <noscript>{数字(索引)1 数字(形式?.skip)}。 无脚本> <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a> </noscript> </li> {/每个} </ol> {#if 形式?.thereIsMore} <input name="searchTerm" type="hidden" value="{form.searchTerm}">> 标签> <button aria-label="加载更多搜索结果的按钮"> <p>现在就这些了。 </p> <p>PS:如果您愿意以不同的方式进行迁移,请随时告诉我。</p> </button>
以上是Svelte 5 中的'助手”变量的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。
