草庐IT

Alpine.js简介:用于最小化列表的JavaScript框架

李睿 2023-04-04 原文

译者 | 李睿

审校 | 孙淑娟

前端JavaScript框架的创新是当今这个时代最伟大的技术文化现象之一。20多年来,人们见证了进化创造力的长尾。每一个新的想法都进行尝试,在软件开发过程和开发人员构建的最终产品中都会促进改进。

Alpine.js是近年来脱颖而出的框架之一。Alpine.js是一个极简主义框架。顾名思义,用于克服大量的困难(在崎岖的山地)进行轻操作。它在一个简洁、易于掌握的软件包中提供了很多的动力。本文将对Alpine.js进行介绍,这样就可以理解它提供了什么,以及它在什么时候可能有用。

Alpine的极简API

正如Alpine.js文档所描述的,Alpine的API是15个属性、6个特性和2个方法的集合。这是一个非常小的API配置文件。其极简主义的目的是以干净的格式提供反应性,并辅以一些周围的细节,例如事件和中央商店。

考虑清单1中非常简单的Web页面。

清单1.一个用Alpine.js构建的简单网页

<html>
<head>
<script src="https://unpkg.com/alpinejs@3.10.3/dist/cdn.min.js" defer></script>
</head>
<body>
<div x-data="">
<span x-text="'Text literal'"></span>
</div>
</body>
</html>

除了通过CDN包含Alpine包,这里仅有的两个与Alpine相关的是指令x-data和x-text。

如果将其放入系统上的HTML页面并在浏览器中查看,将会看到消息输出“文本文字”。虽然这个应用程序不是特别令人印象深刻,但它演示了Alpine的两个有趣方面。

首先,为了使反应性发挥作用,必须将标记包含在x-data指令中。如果删除该指令,则x-text将不会生效。本质上,x-data指令创建了一个Alpine组件。在这个例子中,x-data指令是空的。在实际使用中,这里几乎总是有数据。毕竟,正在编写的组件的目的是响应数据。

清单1中要注意的第二件事是,可以将任何有效的JavaScript放入x-text中。所有的Alpine指令都是如此。

x-data和x-text元素

x-data内容提供给所有包含的元素。要理解这个意思,可以查看清单2。

清单2.x-data和x-text交互

<div x-data="{ message: 'When in the course of human events...' }">
<span x-text="message"></span>
</div>

现在该页面将输出美国《独立宣言》的开头部分。可以看到x-data定义了一个简单的老旧JavaScript对象,只有一个字段“message”,其中包含声明的序言。x-text指向这个对象字段。

在Alpine.js中的反应

接下来,将使用反应性来修复声明中的错误。可以了解清单3。

清单3.x- on:click和反应性

<div x-data="{ pronoun: 'men' }">
<button x-on:click="pronoun = 'people'">Fix It</button>
<span x-text="`all ${pronoun} are created equal`"></span>
</div>

x-text指令指的是由x-data指令公开的代词变量。这里的新部件是按钮,它有一个x-on:click指令。这个单击事件的处理程序将旧的默认代词替换为中性代词,反应性负责更新x-text中的引用。

数据中的函数

Alpine中的数据属性是功能齐全的JavaScript对象。考虑处理上述需求的另一种方法,如清单4所示。

清单4.使用数据函数

<div x-data="{ 
pronoun: 'men',
fixIt: function(){
this.pronoun = 'people';
}
}">
<button x-on:click="fixIt()">Fix It</button>
<span x-text="`all ${pronoun} are created equal`"></span>
</div>

在清单4中,可以看到数据对象现在拥有一个由click处理程序调用的fixIt方法。

另外,有时会看到应用程序代码从x-data指令调用脚本标记中定义的函数——这是个人偏好,它的操作与内联x-data完全相同:

<div x-data="myDataFunction()">...</div>
...
<script>
function myDataFunction() {
return {
foo: "bar"
}
}
</script>

获取远程数据

现在转换话题,可以考虑一个更复杂的需求。假设想从外部API加载一个json格式的美国总统列表。我们要做的第一件事是在页面加载时加载它。为此将使用x-init指令,例如清单5所示。

清单5.从x-init预加载数据

<div x-data="{
presidents: []
}"
x-init="(
async () => {
const response = await fetch('https://raw.githubusercontent.com/hitch17/sample-data/master/presidents.json');
presidents = await response.json();
}
)">
<span x-text="presidents"></span>
</div>

在这里发生了什么?首先,x-data指令应该很清楚它只是有一个带有空数组的总统(presidents)字段。span元素中的x-text输出该字段的内容。

x-init代码有点复杂。首先,注意它被包装在一个自动执行的函数中。这是因为Alpine需要函数,而不是函数定义。(如果要使用fetch的非异步回调形式,则不需要像这样包装函数。)

一旦从端点获得了presidents列表,将其插入到presidents变量中,Alpine将其作为x-data对象的一部分公开。

重申一下:Alpine.js正在使a-data中的数据可用于同一场景中的其他指令函数(例如x-init)。

使用Alpine.js迭代

此时,应用程序正在从远程端点提取数据并将其保存到状态中。需要注意,它输出的内容类似于[Object],[Object]....这不是想要的。可以了解一下遍历数据的过程,例如清单6所示。

清单6.使用Alpine.js迭代

<div x-data=...>
<ul>
<template x-for="pres in presidents">
<li><div x-text="pres.president"></div>
From: <span x-text="pres.took_office"></span> Until: <span x-text="pres.left_office"></span></li>
</template>
</ul>
</div>

清单6包含一个普通的无序列表,后面跟着一个HTML模板元素,其中包含一个x-for指令。这个指令的操作与在其他响应式框架中看到的类似。在本例中,它允许指定一个集合、总统(presidents)和一个标识符,该标识符将提供给表示该集合的每个实例的封闭标记,在本例中为pres。

标记的其余部分使用pres变量通过x-text从对象中输出数据。

其应用程序现在看起来如图1所示。

图1美国总统的名单

显示/隐藏和onClick

现在要设置应用程序,以便通过单击总统的名称来切换总统的数据。首先,将标记修改为清单7所示的内容。

清单7.显示/隐藏元素

<template x-for="pres in presidents">
<li><div x-text="pres.president" x-on:click="pres.show = ! pres.show"></div>
<div x-show="pres.show">
From: <span x-text="pres.took_office"></span> Until: <span x-text="pres.left_office"></span></li>
</div>
</template>

现在,在清单7中,可以在包含总统详细信息的div上使用x-show指令。x-show值的真实性决定内容是否可见。在本例中,这是由pres.show字段决定的 (注意的是,在实际应用程序中,可能不希望使用实际业务数据来承载show/hide变量) 。

为了改变press.show的值,在标头文件中添加一个x-on:click处理程序。这个处理程序简单地交换了press.show的true/false值:press.show=!pres.show。

添加转换动画

Alpine包含内置转换功能,可以应用于显示/隐藏特性。清单8显示了如何添加默认动画。

清单8.添加转换功能来显示/隐藏

<div x-show="pres.show" x-transition>
From: <span x-text="pres.took_office"></span> Until: <span x-text="pres.left_office"></span></li>
</div>

唯一改变的是,带有x-show指令的元素现在也有一个x-transition指令。在默认情况下,Alpine应用合理的转换。在这种情况下,转换是一种滑动和渐变效果。可以广泛地自定义转换,包括将自己的CSS类应用于动画的各个阶段。

绑定到输入

现在,将添加一个简单的过滤器功能。这将需要添加一个绑定到数据的输入,然后根据该值筛选返回的数据集。可以在清单9中看到更改。

清单9.筛选presidents

<div x-data="{
filter: '',
presidents: [],
getPresidents: function(){
return this.presidents.filter(pres => pres.president.includes(this.filter) )
}
}"
...
<input x-model="filter" />
...
<ul>
<template x-for="pres in getPresidents">

注意,x-data对象现在有一个“filter”字段。这是通过指向“filter”的x-model指令双向绑定到输入元素的。

已经更改了模板x-for指令,以引用一个新的getPresidents()方法,该方法在x-data对象上实现。该方法使用标准JavaScript语法,根据总统是否在筛选字段中包含文本来筛选。

结论

就像它的名字一样,Alpine.js是一个轻量级的软件包,里面有着基本的装备,可以“穿越高山”。这是最小的软件包,但已经足够了。

该框架包括一些更高级的功能,特别是中央存储和事件系统,以及插件架构和生态系统。

总之,Alpine.js是符合人体工程学。如果有使用其他响应式框架的经验,那么Alpine应该会很快学会,在x-data指令中声明组件及其数据的简单性。

可能想知道组件间的通信。Alpine.js避免了组件之间的显式连接(例如,没有父-子道具)。与其相反,它通过$dispatch指令使用浏览器环境(即窗口)作为事件总线。这符合Alpine的理念,即添加足够的功能来增强现有的功能。它工作得很好。

随着应用程序的规模和复杂性的增长,所有这些元素都将受到考验。所以它适用于选择的任何堆栈。Alpine.js是下次进行代码冒险的一个诱人选择。

原文标题:Intro to Alpine.js: A JavaScript framework for minimalists作者:Matthew Tyson

有关Alpine.js简介:用于最小化列表的JavaScript框架的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  3. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  4. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  5. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  6. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  7. ruby - 获取数组中的值并最小化某个类属性的最优雅的方法是什么? - 2

    假设我有以下类(class):classPersondefinitialize(name,age)@name=name@age=ageenddefget_agereturn@ageendend我有一组Person对象。是否有一种简洁的、类似于Ruby的方法来获取最小(或最大)年龄的人?如何根据它对它们进行排序? 最佳答案 这样做会:people_array.min_by(&:get_age)people_array.max_by(&:get_age)people_array.sort_by(&:get_age)

  8. ruby - "undefined method"用于 rails 模型 - 2

    我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom

  9. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  10. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

随机推荐