跳转至

x-bind

x-bind 允许你根据 JavaScript 表达式的结果来设置元素的 HTML 属性。

例如,下面是一个组件,我们使用 x-bind 来设置输入框的 placeholder 值。

<div x-data="{ placeholderText: 'Type here...' }">
    <input type="text" x-bind:placeholder="placeholderText">
</div>

简写语法

如果 x-bind: 对你来说过于冗长,你可以使用简写形式::。例如,下面是同一个输入框元素,但改用简写语法:

<input type="text" :placeholder="placeholderText">

尽管上面这段代码中没有包含,但 x-bind 不能在没有父元素定义 x-data 的情况下使用。→ 阅读更多关于 x-data

绑定 class

x-bind 最常见的用途是根据 Alpine 状态为元素设置特定的 class。

下面是一个简单的下拉切换示例,但我们不使用 x-show,而是使用 "hidden" class 来切换元素。

<div x-data="{ open: false }">
    <button x-on:click="open = ! open">Toggle Dropdown</button>

    <div :class="open ? '' : 'hidden'">
        Dropdown Contents...
    </div>
</div>

现在,当 openfalse 时,"hidden" class 会被添加到下拉菜单上。

简写条件判断

在这种情况下,如果你更喜欢更简洁的语法,可以使用 JavaScript 的短路求值(short-circuit evaluation)来代替标准条件判断:

<div :class="show ? '' : 'hidden'">
<!-- 等同于: -->
<div :class="show || 'hidden'">

相反的情况也同样适用。假设我们不使用 open,而是使用一个相反值的变量:closed

<div :class="closed ? 'hidden' : ''">
<!-- 等同于: -->
<div :class="closed && 'hidden'">

Class 对象语法

如果你更喜欢另一种切换 class 的方式,Alpine 提供了一种额外的语法。通过传递一个 JavaScript 对象,其中 class 作为键、布尔值作为值,Alpine 会知道哪些 class 需要应用、哪些需要移除。例如:

<div :class="{ 'hidden': ! show }">

这种技术相比其他方法有一个独特的优势。当使用对象语法时,Alpine 不会保留元素 class 属性上原始的 class。

例如,如果你想在 Alpine 加载之前就给元素应用 "hidden" class,并且在 Alpine 加载后切换它的存在,你只能通过对象语法来实现:

<div class="hidden" :class="{ 'hidden': ! show }">

如果这让你感到困惑,让我们深入了解一下 Alpine 如何处理 x-bind:class 与其他属性的不同。

特殊行为

x-bind:class 在底层的行为与其他属性不同。

考虑以下情况:

<div class="opacity-50" :class="hide && 'hidden'">

如果 "class" 是其他任何属性,那么 :class 绑定会覆盖任何现有的 class 属性,导致 opacity-50hidden'' 覆盖。

然而,Alpine 对 class 绑定的处理有所不同。它足够智能,能够保留元素上现有的 class。

例如,如果 hide 为 true,上面的示例将生成如下的 DOM 元素:

<div class="opacity-50 hidden">

如果 hide 为 false,DOM 元素将如下所示:

<div class="opacity-50">

这种行为对大多数用户来说应该是透明且直观的,但对于好奇的开发者或可能出现特殊情况的场景,还是值得明确提一下。

绑定 style

与使用 JavaScript 对象绑定 class 的特殊语法类似,Alpine 也提供了一种基于对象的语法来绑定 style 属性。

和 class 对象一样,这种语法完全可选。只有在它能为你带来优势时才使用它。

<div :style="{ color: 'red', display: 'flex' }">

<!-- 会渲染为: -->
<div style="color: red; display: flex;" ...>

使用表达式可以实现条件内联样式,就像 x-bind:class 一样。这里也可以使用短路运算符,将样式对象作为第二个操作数。

<div x-bind:style="true && { color: 'red' }">

<!-- 会渲染为: -->
<div style="color: red;">

这种方法的一个优势是可以与元素上已有的样式混合使用:

<div style="padding: 1rem;" :style="{ color: 'red', display: 'flex' }">

<!-- 会渲染为: -->
<div style="padding: 1rem; color: red; display: flex;" ...>

与 Alpine 中的大多数表达式一样,你始终可以使用 JavaScript 表达式的结果作为引用:

<div x-data="{ styles: { color: 'red', display: 'flex' }}">
    <div :style="styles">
</div>

<!-- 会渲染为: -->
<div ...>
    <div style="color: red; display: flex;" ...>
</div>

直接绑定 Alpine 指令

x-bind 允许你将一个包含不同指令和属性的对象绑定到元素上。

对象的键可以是任何你通常作为 Alpine 属性名称写的内容,包括 Alpine 指令和修饰符,也包括普通的 HTML 属性。对象的值可以是普通字符串,或者对于动态 Alpine 指令而言,是交由 Alpine 评估的回调函数。

<div x-data="dropdown">
    <button x-bind="trigger">Open Dropdown</button>

    <span x-bind="dialogue">Dropdown Contents</span>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('dropdown', () => ({
            open: false,

            trigger: {
                ['x-ref']: 'trigger',
                ['@click']() {
                    this.open = true
                },
            },

            dialogue: {
                ['x-show']() {
                    return this.open
                },
                ['@click.outside']() {
                    this.open = false
                },
            },
        }))
    })
</script>

使用 x-bind 的这种形式有几个注意事项:

当被"绑定"或"应用"的指令是 x-for 时,你应该从回调中返回一个普通的表达式字符串。例如:['x-for']() { return 'item in items' }