Alpine.js 中文文档

Alpine.js 中文文档

Alpine.js 提供了像是 Vue 或 React 这样的大型框架的响应式或宣告式的特性,但使用成本却低得多。

你依然可以保留你的 DOM ,并且在你认为合适的时候添加行为。

您可以把 Alpine.js 可选成 JavaScript 的Tailwind

备注:这个工具的语法几乎借鉴了Vue (以及一些Angular的延伸)。 我永远感谢他们为 Web 带来的大礼。

部署

使用 CDN 来源:

在你的 <head> 标签的末端添加以下脚本。

<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>

如果是正式环境,建议在链接中加入一个特定的版本号,避免新版本的升级造成你的程序执行错误。 举个例子,你想固定在 这个版本:2.3.5

<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>

使用 NPM 源:

使用 NPM 程序包安装

npm i alpinejs

在你的脚本中引入它。

import 'alpinejs'

对于 IE11 的支持请使用以下脚本替代。

<script type="module" src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine-ie11.min.js" defer></script>

上述的写法是module/nomodule 模式,它会让现代化网页浏览器自动加载它所需的程序包。 而 IE11 版本的程序包将会在 IE11 上或者是其他的传统网页浏览器上被自动加载。

使用

Dropdown/Modal

<div x-data="{ open: false }">
    <button @click="open = true">Open Dropdown</button>

    <ul
        x-show="open"
        @click.away="open = false"
    >
        Dropdown Body
    </ul>
</div>

Tabs

<div x-data="{ tab: 'foo' }">
    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>

    <div x-show="tab === 'foo'">Tab Foo</div>
    <div x-show="tab === 'bar'">Tab Bar</div>
</div>

你甚至可以用它来实现一些比较复杂的程序:在悬停时预取下拉式菜单的 HTML 内容

<div x-data="{ open: false }">
    <button
        @mouseenter.once="
            fetch('/dropdown-partial.html')
                .then(response => response.text())
                .then(html => { $refs.dropdown.innerHTML = html })
        "
        @click="open = true"
    >Show Dropdown</button>

    <div x-ref="dropdown" x-show="open" @click.away="open = false">
        Loading Spinner...
    </div>
</div>

教学

共有 13 个指令可供你使用:

指令 功能描述
x-data 声明一个新的组件范围。
x-init 当一个组件初始化时,执行一个表达式。
x-show 根据表达式的不同(true 或 false)切换元素是否显示。
x-bind 将属性的数值设定为 JS 表达式的结果。
x-on 附加一个事件监听器到元素上,在触发时执行 JS 表达式。
x-model 替元素附加「双向数据绑定」,同步输入元素与组件数据。
x-text 类似于 x-bind,但会更新元素的 innerText
x-html 类似于 x-bind ,但会更新元素的 innerHTML
x-ref 便利地从组件中取得原始的 DOM 元素。
x-if 从 DOM 中完全删除一个元素,需要在标签 <template> 上使用。
x-for 替数组中的每项创建新的DOM节点,需要在标签 <template> 上使用。
x-transition 将 classes 应用于元素过渡的各个阶段的指令。
x-cloak 此属性在 Alpine 初始化时将被移除,用于隐藏 预初始化的 DOM 。

以及 6 种魔术属性:

魔术属性 功能描述
$el 检索根组件的DOM节点。
$refs 检索组件内标记 x-ref 的 DOM 元素。
$event 检索事件监听器中的浏览器原生「Event」对象。
$dispatch 创建一个并在内部使用进行调度。CustomEvent``.dispatchEvent()
$nextTick 在 Alpine 进行响应式 DOM 更新后执行给定的表达式。
$watch 当你监听的组件属性被改变时,执行回调方法。

指令


x-data

例子: <div x-data="{ foo: 'bar' }">...</div>

结构: <div x-data="[JSON data object]">...</div>

x-data 声明了一个新的组件作用域,它通知框架使用对应的数据对象初始化一个新組件。

想想看,是不是就和 Vue 組件的 data 属性一样。

提取组件逻辑

你可以将数据(和特性)提取到可重用的函数中:

<div x-data="dropdown()">
    <button x-on:click="open">Open</button>

    <div x-show="isOpen()" x-on:click.away="close">
        // Dropdown
    </div>
</div>

<script>
    function dropdown() {
        return {
            show: false,
            open() { this.show = true },
            close() { this.show = false },
            isOpen() { return this.show === true },
        }
    }
</script>

对于 bundler 用户,得注意 Alpine.js 访问函数是在全局范围的(window),你需要显式地将你的函数赋给 window ,以便通过 x-data 来使用它们。例如:window.dropdown = function () {}(这是因为使用 Webpack 、Rollup 与 Parcel 您定义的函数将默认为 module 的作用域而不是window )。

你也可以使用对象解构來混合多数据对象:

<div x-data="{...dropdown(), ...tabs()}">

x-init

例子: <div x-data="{ foo: 'bar' }" x-init="foo = 'baz'"></div>

结构: <div x-data="..." x-init="[expression]"></div>

x-init 在组件初始化时执行一个表达式。

如果你希望在 Alpine 对 DOM 更新之后,再执行表达式(类似于 VueJS 中的 mounted() 钩子),你可以返回一个回调函数

x-init="() => { // 我们可以访问 post-dom-initialization 后的数据 // }"

x-show

例子: <div x-show="open"></div>

结构: <div x-show="[expression]"></div>

x-show  根据表达式结果来切换元素显示状态

x-show.transition

x-show.transition 是一个便捷的使用CSS过渡的 API 。

<div x-show.transition="open">
    These contents will be transitioned in and out.
</div>
指令 功能描述
x-show.transition 同步淡出与缩放 (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
x-show.transition.in 只有「in」过渡。
x-show.transition.out 只有「out」过渡。
x-show.transition.opacity 只使用淡出。
x-show.transition.scale 只使用缩放。
x-show.transition.scale.75 自定 CSS 缩放 。transform: scale(.75)
x-show.transition.duration.200ms 将「in」过渡设定为 200毫秒。 「out」将设定为 in 的一半(100 毫秒)。
x-show.transition.origin.top.right 自定义 CSS 过渡起始点.transform-origin: top right
x-show.transition.in.duration.200ms.out.duration.50ms 「in」与「out」设定不同的持续时间。

备注:这些过渡的修饰符都是可以相互配合使用,这个例子是可行的(虽然很荒谬,呵呵):x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95

备注::x-show 会等待所有子元素完成过渡,如果你想省略这个行为,请添加 .immediate 修饰符

<div x-show.immediate="open">
    <div x-show.transition="open">
</div>

x-bind

备注:你可以自由使用较短的":" 语法::type="..."

示例 : <input x-bind:type="inputType">

结构 : <input x-bind:[attribute]="[expression]">

x-bind 将一个属性值设定为 JavaScript 表达式的结果。 这个表达式可以访问组件的数据对象的所有键,并且每次更新数据时都会同步更新。

备注:属性绑定只有在其依赖的关系被更新时才会更新,框架足够智能,观察到数据更改并检测哪些绑定关心它们。

用于类别属性的x-bind

x-bind 与 `class` 属性在绑定时的行为会有点不同。

对于 classes 而言,当你传递一个键为 class 名称的对象,值则是 boolean表达式来决定是否应该要应用这些 class 。

举例来说: <div x-bind:class="{ 'hidden': foo }"></div>

在这个范例中,只有当 footrue时,hidden 类别才会被应用。

用于布尔属性的x-bind

x-bind` 支持与数值属性相同的布尔属性,使用变量作为条件或任何可以解析为`true` or `false` 的JavaScript 表达式。

举例来说:

<!-- Given: -->
<button x-bind:disabled="myVar">Click me</button>

<!-- When myVar == true: -->
<button disabled="disabled">Click me</button>

<!-- When myVar == false: -->
<button>Click me</button>

这将在 myVar 为true或false时分别添加或删除disabled`属性。

布尔属性将支持符合HTML规范的属性,例如: disabledreadonlyrequiredcheckedhiddenselectedopen 等。


x-on

备注:你可以自由使用较短的"@」 语法:@click="..."

示例 : <button x-on:click="foo = 'bar'"></button>

结构 : <button x-on:[event]="[expression]"></button>

x-on 会将一个事件监听器附加在它所声明的元素上,当这个事件被触发时,在其值所设定的 JavaScript 表达式将会被执行。

如果任何数据在这个表达式中被修改,那么与这个被修改的数据所「绑定」的元素属性也会随着更新。

**keydown修饰符

示例 : <input type="text" x-on:keydown.escape="open = false">

你可以使用附加到 x-on:keydown 指令中的 keydown 修饰符,指定要监听的特定键值。 请注意,这些修饰符的命名方式是短横线连接式。

例如: enterescapearrow-uparrow-down

备注:你也可以监听系统修饰符的键值组合,例如:x-on:keydown.cmd.enter="foo"

.away修饰符

范例: <div x-on:click.away="showModal = false"></div>

当 修饰符存在时,则仅当事件源自其自身或其子级以外的其他源时,才执行事件处理程序。

当用户点击 dropdowns and modals 时,这对于隐藏它们是非常有用的。

.prevent修饰器

范例: <input type="checkbox" x-on:click.prevent>

将.prevent添加到事件监听器将会在触发的事件上调用preventDefault。在上面的示例中,这意味着当用户单击该复选框时,它实际上不会被选中。

.stop修饰器

范例: <div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>

将.stop添加到事件侦听器将在触发的事件上调用stopPropagation。在上面的示例中,这意味着“点击”事件不会从按钮到外部冒泡。换句话说,当用户单击按钮时,foo将不会设置为“ bar”。

.self修饰器

范例: <div x-on:click.self="foo = 'bar'"><button></button></div>

如果$ event.target是元素本身,则将.self添加到事件侦听器将仅触发处理程序。在上面的示例中,这意味着从按钮到外部冒泡的“ click”事件将不会运行处理程序。

.window修饰器

范例: <div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>

将.window添加到事件侦听器会将侦听器安装在全局窗口对象上,而不是在声明该侦听器的DOM节点上。当您希望随着窗口的变化(例如调整大小事件)而修改组件状态时,这很有用。在此示例中,当窗口变得大于768像素宽时,我们将关闭模式/下拉菜单,否则保持相同状态。

备注:你也可以使用.document 修饰符,将监听器加入到 document 中,而不是加入到window 中。

.once修饰器

范例: <button x-on:mouseenter.once="fetchSomething()"></button>

将.once修饰符添加到事件侦听器将确保该侦听器仅被处理一次。这对于只想执行一次的事情很有用,例如获取HTML局部等。

.debounce修饰器

范例: <input x-on:input.debounce="fetchSomething()">

debounce修饰符使您给事件处理程序加上「防抖动机制。换句话说,事件处理程序要等到自上一次触发事件起经过一定时间后才会运行。准备好调用处理程序时,将执行最后一个处理程序调用。默认的 debounce 等待时间是 250 毫秒。

如果您希望对此进行自定义,则可以指定自定义等待时间,如下所示:

<input x-on:input.debounce.750="fetchSomething()">
<input x-on:input.debounce.750ms="fetchSomething()">

x-model

示例 : <input type="text" x-model="foo">

结构 : <input type="text" x-model="[data item]">

x-model 将“双向数据绑定”添加到元素。换句话说,输入元素的值将与组件的数据项的值保持同步。

备注: x-model将会智能地察觉到 inputs 、 checkboxes 、 radio buttons 、 textareas 、 selects 以及 multiple selects 的变化。 在这些情形下,它的行为将会跟Vue有着一样的表现。

.debounce修饰器

范例: <input x-model.debounce="search">

debounce 修饰器允许你替事件处理程序加上「防抖动」机制,换而言之,事件处理程序将不会立即被运作,它会自事件触发后等待一段时间才会开始运作。 当处理程序准备好被呼叫时,最后一个处理程序的呼叫将被执行。

默认的 debounce 等待时间是 250 毫秒。

如果你想自定义这个时间,可以像这样指定自定义的等待时间:

<input x-model.debounce.750="search">
<input x-model.debounce.750ms="search">

x-text

例子: <span x-text="foo"></span>

结构: <span x-text="[expression]"

x-text 的工作原理与 x-bind 类似 ,只是它不會更新元素的值,而是更新元素的 innerText。

x-html

例子: <span x-html="foo"></span>

结构: <span x-html="[expression]"

x-text 的工作原理与 x-bind 类似,只是它不会更新元素的值,而是更新元素的 innerHTML。

⚠️ 只有在可信赖的内容使用这个特性,决定不要相信用户提供的内容 ⚠️

使用第三方內容动态生成的 HTML 很容易导致 XSS 漏洞的发生。


x-ref

例子: <div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>

结构: <div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>

x-ref` 提供了一個便利的方法让你从你的组件中获取到原始的 DOM 元素。通过在一個元素上设定一个`x-ref`属性,你就可以在 $refs 中调用所有的事件处理程序。

这是设置ID并在各处使用document.querySelector的有用替代方法。

备注:如果你需要的话,也可以为 x-ref 绑定动态值: <span :x-ref="item.id"></span>


x-if

例子: <template x-if="true"><div>Some Element</div></template>

结构: <template x-if="[expression]"><div>Some Element</div></template>

对于x-show不够的情况(x-show设置要显示的元素:如果为false,则不显示),可以使用x-if实际从DOM中完全删除元素。

在标签上使用 x-if 很重要,因为Alpine不使用虚拟DOM。此实现使Alpine保持坚固耐用,并使用真实的DOM发挥其魔力。

备注:x-if 必须在<template></template>标签内拥有根元素。


x-for

示例 :

<template x-for="item in items" :key="item">
    <div x-text="item"></div>
</template>

备注: :key 绑定是可选的,但强烈建议你使用。

如果要为数组中的每个项目创建新的DOM节点,则可以使用x-for。这应该类似于Vue中的v-for,但需要存在于模板标签上,而不是常规DOM元素上。

如果你想访问当前索引,请使用下列语法:

<template x-for="(item, index) in items" :key="index">
    <!-- 如果你需要的话,也可以在迭代的內部引用「index」-->
    <div x-text="index"></div>
</template>

备注: x-for必须在<template></template>标签内拥有根元素的情形下使用。

嵌套 x-for

你也可以嵌套 x-for ,但你必须将每个循环都包裹在一个元素中,比如说:

<template x-for="item in items">
    <div>
        <template x-for="subItem in item.subItems">
            <div x-text="subItem"></div>
        </template>
    </div>
</template>

x-transition

示例 :

<div
    x-show="open"
    x-transition:enter="transition ease-out duration-300"
    x-transition:enter-start="opacity-0 transform scale-90"
    x-transition:enter-end="opacity-100 transform scale-100"
    x-transition:leave="transition ease-in duration-300"
    x-transition:leave-start="opacity-100 transform scale-100"
    x-transition:leave-end="opacity-0 transform scale-90"
>...</div>
<template x-if="open">
    <div
        x-transition:enter="transition ease-out duration-300"
        x-transition:enter-start="opacity-0 transform scale-90"
        x-transition:enter-end="opacity-100 transform scale-100"
        x-transition:leave="transition ease-in duration-300"
        x-transition:leave-start="opacity-100 transform scale-100"
        x-transition:leave-end="opacity-0 transform scale-90"
    >...</div>
</template>

上述范例使用了Tailwind CSS中的类别。

Alpine提供了6种不同的过渡指令,用于将类应用于元素在“隐藏”状态和“显示”状态之间过渡的各个阶段。这些指令与x-show和x-if一起使用。

这些指令的行为与 VueJs 的过渡指令完全相同,除了它们有一个更加地合理名字:

指令 功能描述
:enter 在整个 entering 阶段中应用。
:enter-start 在元素插入前添加,在元素插入后删除一个帧。
:enter-end 元素在插入后添加一帧(同時刪除 ),在过渡/动画结束时刪除。
:leave 在整个 leaving 阶段中应用。
:leave-start 触发离开过渡时立即添加,在一帧后移除。
:leave-end 触发离开过渡后添加一帧(同时删除离开开始),在过渡/动画结束时删除。

x-cloak

Example : <div x-data="{}" x-cloak></div>

当Alpine初始化时,x-cloak属性将从元素中删除。这对于隐藏预初始化的DOM很有用。通常,添加以下全局样式才能使其正常工作:

<style>
    [x-cloak] { display: none; }
</style>

魔术属性


除了 $el 之外,x-data 中的魔术属性不可用,因为该组件尚未初始化。

$el

示例 :

<div x-data>
    <button @click="$el.innerHTML = 'foo'">Replace me with "foo"</button>
</div>

$el 是一个魔术属性,可以用来检索根组件的 DOM 节点。

$refs

示例 :

<span x-ref="foo"></span>

<button x-on:click="$refs.foo.innerText = 'bar'"></button>

$ refs是一个魔术属性,可用于检索组件内部标有x-ref的DOM元素。当您需要手动操作DOM元素时,这很有用。

$event

示例 :

<input x-on:input="alert($event.target.value)">

$ event是一个魔术属性,可以在事件侦听器中使用它来检索本机浏览器“ Event”对象。

注意:$ event属性仅在DOM中可用。

如果您需要在JavaScript函数中访问$ event,则可以直接将其传递:

<button x-on:click="myFunction($event)"></button>

$dispatch

示例 :

<div @custom-event="console.log($event.detail.foo)">
    <button @click="$dispatch('custom-event', { foo: 'bar' })">
    <!-- When clicked, will console.log "bar" -->
</div>

$ dispatch是创建CustomEvent并在内部使用.dispatchEvent()调度它的快捷方式。有很多很好的用例,可以使用自定义事件在组件之间以及组件之间传递数据。 在此阅读 有关浏览器中CustomEvent系统的更多信息。

你可能发现了,任何作为第二个参数传入到的数据,都会通过新的事件「detail」属性提供提供: 。 将自定义的事件资料附加到 属性是浏览器中的标准做法。 阅读这里了解更多信息。$dispatch('some-event', { some: 'data' })``$event.detail.some``.detail``CustomEvent

你也可以使用 $dispatch() 来触发 所绑定的数据更新,比如说:

<div x-data="{ foo: 'bar' }">
    <span x-model="foo">
        <button @click="$dispatch('input', 'baz')">
        <!-- After the button is clicked, `x-model` will catch the bubbling "input" event, and update foo to "baz". -->
    </span>
</div>

$nextTick

示例 :

<div x-data="{ fruit: 'apple' }">
    <button
        x-on:click="
            fruit = 'pear';
            $nextTick(() => { console.log($event.target.innerText) });
        "
        x-text="fruit"
    ></button>
</div>

$ nextTick是一个神奇的属性,允许您仅在Alpine完成反应式DOM更新后才执行给定的表达式。这在您想要与DOM状态进行交互之后反映出所做的任何数据更新时非常有用。

$watch

示例 :

<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
    <button @click="open = ! open">Toggle Open</button>
</div>

您可以使用$ watch magic方法“监视”组件属性。在上面的示例中,当单击按钮并更改了打开时,将触发提供的回调并console.log新值。

安全

如果你发现了安全漏洞,请发送电子邮件至[email protected]

Alpine依靠使用Function对象的自定义实现来评估其指令。尽管比eval()更安全,但在某些环境(例如Google Chrome应用)中,使用限制性内容安全策略(CSP)禁止使用它。

如果您在处理敏感数据并需要CSP的网站中使用Alpine,则需要在策略中包括不安全评估。正确配置的可靠策略将有助于在使用个人或财务数据时保护用户。

由于政策适用于您页面中的所有脚本,因此请务必仔细查看网站中包含的其他外部库,以确保它们值得信赖,并且不会使用eval()函数或操作任何跨站脚本漏洞,这一点很重要。 DOM将恶意代码注入您的网页。

V3 路线图

  • Move from x-ref to ref for Vue parity?
  • Add Alpine.directive()
  • Add Alpine.component('foo', {...}) (With magic __init() method)
  • Dispatch Alpine events for "loaded", "transition-start", etc... (#299) ?
  • Remove "object" (and array) syntax from x-bind:class="{ 'foo': true }" (#236 to add support for object syntax for the style attribute)
  • Improve x-for mutation reactivity (#165)
  • Add "deep watching" support in V3 (#294)
  • Add $el shortcut
  • Change @click.away to @click.outside?

授权条款

Copyright © 2019-2020 Caleb Porzio and contributors

Licensed under the MIT license, see LICENSE.md for details.

翻译对照表

英文 文档采用译名
animation 动画
binding 绑定
callback 回调
components 组件
declarative 声明式
destructuring 解构
debounce 防抖动
dropdown 下拉式菜单
expression 表达式
handler 处理器
insert 插入
kebab-case 短横线连接式
listener 监听器
modifier 修饰符
modals 交互式窗口
nesting 嵌套
package 软件包
reactive 响应式
tabs tabs
transition 过渡
two-way data binding 双向数据绑定