用Alpine.js增強前端交互
这篇帖子是关于在客户端实现异步请求的不同方法的一系列文章之一,这种异步请求在中文中俗称 AJAX。我在上一篇帖子中介绍了 Vue.js;这次我将介绍 Alpine.js —— 不要与 Alpine Linux 混淆。
我还是按照之前的方式来做。
规划工作这里说的是服务器端和客户端的设置。
服务端这是我如何在POM文件中整合Thymeleaf和Alpine.js的方法:
<dependencies>
<依赖关系>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <!--1-->
</依赖关系>
<依赖关系>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId> <!--1-->
</依赖关系>
<依赖关系>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId> <!--1-->
<version>版本号 0.52</version>
</依赖关系>
<依赖关系>
<groupId>org.webjars.npm</groupId>
<artifactId>alpinejs</artifactId> <!--2-->
<version>版本号 3.14.1</version>
</依赖关系>
<依赖关系>
<groupId>org.webjars.npm</groupId>
<artifactId>axios</artifactId> <!--1-->
<version>版本号 1.7.3</version>
</依赖关系>
</dependencies>
- 和上周一样,使用 Vue
- 用 Alpine 替代 Vue
这和 Vue 的 setup 类似。
客户端这边这是HTML那边的代码段:
<script th:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@{/webjars/axios/dist/axios.js}" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/axios@1.7/dist/axios.min.js"></script> <!--1-->
<script th:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@{/webjars/alpinejs/dist/cdn.js}" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/alpinejs@3.14.1/dist/cdn.min.js" defer></script> <!--2-->
<script th:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@{/alpine.js}" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="../static/alpine.js"></script> <!--3-->
<script th:inline="javascript">
/*<![CDATA[*/
window.alpineData = { <!--4-->
title: /*[[${ title }]]*/ 'A Title',
todos: /*[[${ todos }]]*/ [{ 'id': 1, 'label': '去扔垃圾', 'completed': false }]
}
/*]]>*/
</script>
- Axios 帮助我们发送 HTTP 请求
- 就 Alpine 本身而言
- 我们的客户端代码
- 设定数据值
在 Alpine 和 Vue 中,POM 的代码是一样的。
阿尔派斯码我们也想实现跟 Vue 一样的功能。
我们第一次走进阿尔派恩首先,我们要初始化框架。我们在上面已经添加了自定义的alpine.js
文件链接。
document.addEventListener('alpine:init', () => { //1
Alpine.data('app', () => ({ //2
// JS 代码片段将在这个块内
}))
})
- 在触发
alpine:init
事件时运行此块;这里的事件是 Alpine 特定的。 - 启动 Alpine 并配置它来管理标识为
app
的 HTML 片段。
我们现在在HTML中设置了app
ID。
<div id="app"> </div> <!-- 这是一个包含应用内容的div元素 -->
直到现在为止,它与 Vue.js 极其相似,是一一对应的。
与 Vue.js 不同,Alpine 看起来没有 模板。官方的 UI 组件 并不免费。我发现了一个 开源组件,但在 WebJars 上不可获取。
基本互动咱们实现全选复选框的检查。
下面的HTML代码是:
<input type="checkbox" :checked="待办事项已完成" @click="check(待办事项ID)"> <!--1-->
<input type="checkbox" :checked="待办事项已完成" @click="检查" /> <!--2-->
注释1:当点击复选框时,将根据待办事项ID执行检查操作。
注释2:当点击复选框时,将执行检查操作。
- 基于 Alpine 的代码
- Vue.js 代码
代码非常相似,只是唯一的不同是,Alpine允许传递参数。
在 Javascript 这边,我们必须定义这个函数,就这样就行了:
Alpine.data('app', () => ({
check(id) {
axios.patch(`/api/todo/${id}`, {checked: event.target.checked})
}
}))
客户端模型
你可能想知道上面的 todo
是从哪里来的呢?答案是:它来自本地模型。
我们在这个 app
里初始化它,更准确地说,我们初始化这个列表。
Alpine.data('app', () => ({
title: window.alpineData.title, // 标题
todos: window.alpineData.todos, // 任务列表
}))
- 即使
title
是只读的,也要初始化它 - 初始化
todos
列表,此时它是只读的,但我们将在下一节更新它
在这部分中,我们将实现添加一个新的 Todo
。
下面是一个 HTML 示例代码:
<form>
<div class="form-group row">
<label for="new-todo-label" class="col-auto col-form-label">新建任务</label>
<div class="col-10">
<input type="text" id="new-todo-label" placeholder="标签名" class="form-control" x-model="label" /> <!--1-->
</div>
<div class="col-auto">
<button type="button" class="btn btn-success" @click="create()">添加任务</button> <!--2-->
</div>
</div>
</form>
x-model
定义了一个模型,并将app
中的label
属性绑定到这个模型上- 定义按钮的行为,就像在前面的部分中提到的那样
相关代码如下:
Alpine.data('app', () => ({
label: '', //1
create() {
// 使用axios.post('/api/todo') 发送带有 {label: this.label} 数据的POST请求到 '/api/todo' 端点
axios.post('/api/todo', {label: this.label}).then(response => { //2
// 将响应数据添加到this.todos数组中
this.todos.push(response.data) //3
}).then(() => {
// 将this.label重置为空字符串
this.label = '' //4
})
}
}))
- 定义一个新的
label
属性值 - 发送一个包含
label
值的POST
请求,其中 JSON 负载为label
值 - 从响应中获取负载,并将其添加到本地的
Todo
模型中 - 将
label
值重置
阿尔派与 Vue 很相似,主要区别是没有模板;组件需要付费才能获取。所有其他功能都有相应的实现。
我可能需要纠正,因为文档不太详细。再说一个点,Vue 相比 Alpine 更受欢迎。
这篇帖子的完整源代码可以在GitHub(吉特霍布)上找到。
GitHub - ajavageek/compare-frontends: AJAX和SSR系列的演示项目代码。欢迎通过GitHub参与开发。github.com要了解更多:
-
原发表于A Java Geek ,2024年9月29日
共同學習,寫下你的評論
評論加載中...
作者其他優(yōu)質文章