发布于 2026-01-06 3 阅读
0

首先是 AlpineJS DEV 的全球展示与讲述挑战赛,由 Mux 呈现:展示你的项目!

从 AlpineJS 开始

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

注:源代码可以在我的Github上找到

如今,JavaScript 框架、库和工具层出不穷,让人难以抉择。

我个人比较喜欢用Angular,但React和Vue越来越受欢迎。有些框架,比如KnockoutJS,现在几乎被人遗忘了,而另一些框架,比如Reason(与其说是框架,不如说是编程语言)和SvelteJS,则越来越受欢迎。

所以,虽然我打算开始学习 React(也该是时候了),但我还是忍不住尝试了一个大约一个月前推出的新挑战者。

欢迎AlpineJS

AlpineJS 旨在成为一个比 Vue 或 React 轻量得多的库,同时其语法完全借鉴自 Vue(引用作者的话)。

为什么选择 AlpineJS?

你说得对:既然有那么多其他工具,而且这些工具都有庞大的用户群体,为什么还要费劲地再次学习一个新工具呢?

以下是一些优点:

  • 你可以从一开始就见证一个库的发展历程,而且,为什么不呢?你还可以做出贡献;
  • 我预感 AlpineJS 在 2020 年一定会获得一定的知名度;
  • 虽然 React 和 Vue 受到了很多开发者的推崇,但 AlpineJS 提供了一种更轻量级的 Web 前端开发方式,比当今的框架更接近基础知识(而我确实很喜欢基础知识)。

缺点:

  • 它是新的,所以并不完美;
  • 你可能要花点时间才能弄明白它的实际运作方式;
  • 我之前说过,我预感这个框架将来会流行起来,但你不能确定这一点。

它是如何运作的?

让我们来编写第一个组件!我们将编写一个非常简单极简的待办事项列表。本文不会提供完整的解决方案,因为在我撰写本文时,AlpineJS 仍在开发中。
后续会有更新。

设置环境

首先,让我们安装 AlpineJS。

npm i alpinejs

本示例将使用 Node 包 AlpineJS,但您也可以使用 CDN。
正如文档中所述,我们需要添加一些针对 IE11 的 polyfill。

所以,创建一个名为 `<directory_name>` 的目录src。从现在开始,我们将把所有应用程序文件都创建在这个目录中。然后,创建一个index.html包含以下代码的 `<directory_name>`:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>TODO LIST - ALPINEJS</title>
    <link rel="stylesheet" href="./css/tasks.css">
    <script src="https://polyfill.io/v3/polyfill.min.js?features=MutationObserver%2CArray.from%2CArray.prototype.forEach%2CMap%2CSet%2CArray.prototype.includes%2CString.prototype.includes%2CPromise%2CNodeList.prototype.forEach%2CObject.values%2CReflect%2CReflect.set"></script>
    <script src="https://cdn.jsdelivr.net/npm/proxy-polyfill@0.3.0/proxy.min.js"></script>
</head>
<body>
    <section id="add-task-container">
        <form>
            <input type="text">
            <button type="submit">Add task</button>
        </form>
    </section>
    <section id="list-tasks-container">
    </section> 
</body>
</html>

好了,我们已经有了所需的文件index.html,这很好。现在,我们需要导入 AlpineJS 模块。
由于我们将其安装为 Node 模块,因此导入它的一种方法是app.js在名为 `<module_name>` 的目录中创建一个名为 `<module_name>` 的文件cjs-modules,并使用如下的CommonJS规范:

'use strict'
let Alpine = require('alpinejs');

// DO NOT WRITE Alpine.start(); or every event will fire twice

但是现在,我们的app.js文件是一个 Node 模块,不能在前端脚本和 HTML 页面中使用,对吧?
幸运的是,有一个名为gulp-bro的 Node 包(gulp-browserify目前已被 NPM 列入黑名单)。这个包允许我们使用Browserify,这是一个强大的工具,可以在前端应用程序中使用 Node 模块。

所以,在你的终端中:

npm install -D gulp gulp-bro

我们为什么要使用这个gulp?这纯粹是我随意选择的。你也可以使用gruntwebpack或其他任何库。我们还会用到一个名为browser-sync的包。BrowserSync 允许你在修改代码时实时刷新浏览器。

npm install -D browser-sync

现在,回到我们的index.html文件。
只需添加以下内容:

<script src="./app.js"></script>

在进行任何测试之前,我们还需要设置开发环境。我们将在gulpfile.js项目根目录下创建一个 Gulp 作业。

请写出以下内容:

// src and dest are for moving files
// watch is for Gulp to trigger tasks anytime the watched files are modified
// task is to register a task in Gulp
const { src, dest, watch, task } = require('gulp');

// bro is for browserify
const bro = require('gulp-bro');

// browserSync
const browserSync = require('browser-sync').create();

// our build function
function _build() {
    // take every commonJS module, browserify them and put them into ./dist
    src('./src/cjs-modules/*.js')
        .pipe(bro())
        .pipe(dest('./dist'));

    // take every JS script, and put them into ./dist
    src('./src/scripts/**/*.js')
        .pipe(dest('./dist'));

    // take every HTML and CSS and put them into ./dist
    src(['./src/**/*.html', './src/**/*.css'])
        .pipe(dest('./dist'));
}

// our watch function
function _watch() {
    watch(['src/*/*.js', 'src/**/*.html'], _build);
    watch(['src/*/*.js', 'src/**/*.html']).on('change', browserSync.reload);
}

// our serve function
function _serve() {
    _build();
    browserSync.init({
        server: "./dist"
    });

    _watch();
}

// registering a 'serve' task so we can trigger the building and serving with
// gulp serve
task('serve', _serve);

好了,现在我们到这里。这应该是你进行任何测试之前的最低设置。但我们还没完全完成。在你的package.json文件中,添加以下脚本:

"start": "gulp serve"

这样,您可以通过输入任一命令来启动构建和应用npm start程序gulp serve

首次发布

npm start使用或启动应用程序gulp serve。如果一切正常,您应该会看到一个包含输入框、按钮的页面,并且浏览器控制台中不会出现错误

数据绑定

AlpineJS使用任何虚拟 DOM。这确实是一个不小的挑战,但它使我们能够开发出速度更快的应用程序。

首先,AlpineJS 是如何处理数据绑定的?

根据文档,您可以使用一些指令。其中之一是 `@variables`x-data指令。该指令允许您声明将在页面/组件中使用的变量。

这里,我们将使用两个变量:

  • 任务,最初只会包含一个标签;
  • tasks,这将是一个数组,用于存放我们将要创建的所有任务;

所以,在容器上<body><section>写入:

<body x-data="{tasks: [], task: {label: ''}}">

我们稍后会用到这些变量。

现在,我们需要将一些数据绑定到表单。与 Angular 类似,AlpineJS 提供了一个名为 `<input type="data">` 的指令x-model,我们可以用它来实现双重绑定。这里,我们将使用 `<input type="data">` 指令将数据绑定taskx-data输入框。请按如下方式更新您的 HTML:

<input type="text" x-model="task.label">

现在,我们在输入框中输入的所有内容都会影响到label我们task变量的属性。

这固然很好,但仍然存在一个问题(以及其他一些问题):当我们点击“提交”按钮时,页面会重新加载。这是表单和提交按钮的默认行为。
幸运的是!AlpineJS 提供了一个x-on指令,可以用来处理事件!

它的其中一个特性是x-on:[event name].prevent,其功能与相同event.preventDefault()
因此,在您的<form>标签中添加以下内容:

<form x-on:submit.prevent>

这样一来,点击提交按钮时页面就不会再重新加载了。

添加任务

由于 AlpineJS 尚未完成,我们需要做一些工作才能实现我们想要的目标。

首先,我们希望将一个行为绑定到点击事件上,以便在提交表单时触发。所以:

<button type="submit" x-on:click="tasks = addTask(task, tasks);">Add task</button>

现在,我们需要实现这个addTask方法。

创建一个名为 `<directory_name>` 的目录scripts,并在其中创建一个名为 `<script_name>` 的脚本functions.js。为了简单起见,我们暂时将所有函数都存储在该文件中。

在这个文件中,创建一个名为 `add` 的函数addTask。该函数将接受两个参数:要添加的任务和要将任务添加到的列表。

function addTask(task, tasks) {
    // if we do something like [...tasks, task], then we will
    // still have a reference over the task object, which is bound with
    // x-model, making our list to have multiple references to this object
    // And we do not want that.
    return [...tasks, {...task}]
}

别忘了把它链接到你的HTML代码中:

<script src="./functions.js"></script>

在继续之前:为什么我们不直接使用 `this.js` 呢tasks.push(task)?嗯,目前来说,如果我们这样做,HTML 中绑定的变量将不会更新,我们将无法显示其内容。因此,我们需要返回一个更新后的副本,然后重新应用它,这样我们的 HTML 才能更新。

显示任务

遗憾的是,AlpineJS 目前尚未提供此x-for功能(详情请见此处)。这里有一个关于该x-html指令的PR

我们仍然可以通过以下方式展示数据:

<section id="list-tasks-container" x-text="JSON.stringify(tasks)">
</section>

通常情况下,每次按下“提交”按钮时,数据都会刷新并显示。

贡献

AlpineJS 正在蓬勃发展,但仍需要您的帮助和支持。欢迎您为这个极具潜力的框架贡献力量,并参与测试和试用。

随着 AlpineJS 的发展,本文将不时更新。

如果您觉得我的说明有任何不清楚的地方,或者您采用了其他方法,请随时告诉我。我也很想听听您对使用 AlpineJS 进行开发时的最佳实践有何看法。

感谢阅读!

文章来源:https://dev.to/nugetchar/starting-with-alpinejs-hjn