alpinejs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Alpine.js Development

Alpine.js 开发指南

Build reactive, declarative interfaces by adding Alpine.js directives directly to HTML markup.
通过直接在HTML标记中添加Alpine.js指令,构建响应式、声明式界面。

What is Alpine.js

什么是Alpine.js

Alpine.js is a lightweight JavaScript framework that provides reactive and declarative behavior directly in HTML markup. It offers Vue-like syntax and reactivity without the build step, making it perfect for enhancing static sites or adding interactivity to server-rendered pages.
Key characteristics:
  • No build step required - include via CDN or npm
  • Declarative syntax using HTML attributes (directives)
  • Reactive data binding and state management
  • Small footprint (~15kb gzipped)
  • Works seamlessly with server-rendered HTML
Alpine.js是一款轻量级JavaScript框架,可直接在HTML标记中提供响应式和声明式行为。它拥有类Vue的语法和响应式能力,无需构建步骤,非常适合增强静态站点或为服务端渲染页面添加交互性。
核心特性:
  • 无需构建步骤 - 通过CDN或npm引入
  • 使用HTML属性(指令)的声明式语法
  • 响应式数据绑定与状态管理
  • 体积小巧(压缩后约15kb)
  • 与服务端渲染HTML无缝兼容

Installation

安装

Via CDN (Quick Start)

通过CDN(快速开始)

Add the script tag to your HTML
<head>
:
html
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
The
defer
attribute ensures Alpine loads after the HTML is parsed.
在HTML的
<head>
中添加脚本标签:
html
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
defer
属性确保Alpine在HTML解析完成后加载。

Via npm

通过npm

bash
npm install alpinejs
Then import and initialize:
javascript
import Alpine from 'alpinejs'
window.Alpine = Alpine
Alpine.start()
bash
npm install alpinejs
然后导入并初始化:
javascript
import Alpine from 'alpinejs'
window.Alpine = Alpine
Alpine.start()

Core Concepts

核心概念

State with x-data

使用x-data管理状态

Declare reactive state using the
x-data
directive. All Alpine components start with
x-data
:
html
<div x-data="{ count: 0, message: 'Hello' }">
  <!-- State is accessible within this element and its children -->
</div>
Key points:
  • Define data as a JavaScript object
  • Properties are reactive - changes trigger UI updates
  • Data is scoped to the element and its children
  • Child elements can override parent data properties
使用
x-data
指令声明响应式状态。所有Alpine组件都以
x-data
开头:
html
<div x-data="{ count: 0, message: 'Hello' }">
  <!-- 状态可在该元素及其子元素中访问 -->
</div>
关键点:
  • 以JavaScript对象形式定义数据
  • 属性具备响应式 - 变更会触发UI更新
  • 数据作用域限定在该元素及其子元素内
  • 子元素可覆盖父元素的数据属性

Event Handling with x-on

使用x-on处理事件

Listen to browser events using
x-on:
or the
@
shorthand:
html
<button @click="count++">Increment</button>
<button x-on:click="count++">Increment (verbose)</button>
Common event modifiers:
  • .prevent
    - Prevent default behavior
  • .stop
    - Stop event propagation
  • .outside
    - Trigger when clicking outside element
  • .window
    - Listen on window object
  • .debounce
    - Debounce the handler
Key-specific listeners:
html
<input @keyup.enter="submit()">
<input @keyup.shift.enter="specialSubmit()">
使用
x-on:
或简写
@
监听浏览器事件:
html
<button @click="count++">递增</button>
<button x-on:click="count++">递增(完整写法)</button>
常用事件修饰符:
  • .prevent
    - 阻止默认行为
  • .stop
    - 阻止事件冒泡
  • .outside
    - 在点击元素外部时触发
  • .window
    - 在window对象上监听
  • .debounce
    - 防抖处理
特定按键监听:
html
<input @keyup.enter="submit()">
<input @keyup.shift.enter="specialSubmit()">

Templating and Display

模板与显示

x-text - Set element text content:
html
<span x-text="message"></span>
x-html - Set element HTML (use only with trusted content):
html
<div x-html="htmlContent"></div>
x-show - Toggle visibility with CSS display property:
html
<div x-show="isVisible">Content</div>
x-if - Conditionally add/remove element from DOM:
html
<template x-if="shouldShow">
  <div>Content</div>
</template>
When to use x-show vs x-if:
  • Use
    x-show
    when toggling frequently (keeps element in DOM)
  • Use
    x-if
    when conditionally rendering expensive content
x-text - 设置元素文本内容:
html
<span x-text="message"></span>
x-html - 设置元素HTML内容(仅用于可信内容):
html
<div x-html="htmlContent"></div>
x-show - 通过CSS display属性切换可见性:
html
<div x-show="isVisible">内容</div>
x-if - 条件性地在DOM中添加/移除元素:
html
<template x-if="shouldShow">
  <div>内容</div>
</template>
x-show与x-if的使用场景:
  • 当需要频繁切换时使用
    x-show
    (元素保留在DOM中)
  • 当需要条件渲染开销较大的内容时使用
    x-if

Looping with x-for

使用x-for循环

Iterate over arrays to render lists:
html
<template x-for="item in items" :key="item.id">
  <li x-text="item.name"></li>
</template>
Requirements:
  • Must be on a
    <template>
    element
  • Should include
    :key
    for proper tracking
遍历数组渲染列表:
html
<template x-for="item in items" :key="item.id">
  <li x-text="item.name"></li>
</template>
要求:
  • 必须作用于
    <template>
    元素
  • 应包含
    :key
    以确保正确追踪

Binding Attributes with x-bind

使用x-bind绑定属性

Dynamically bind HTML attributes using
x-bind:
or
:
shorthand:
html
<img :src="imageUrl" :alt="description">
<button :disabled="isProcessing">Submit</button>
Class binding (special object syntax):
html
<div :class="{ 'active': isActive, 'error': hasError }">
Style binding:
html
<div :style="{ color: textColor, fontSize: size + 'px' }">
使用
x-bind:
或简写
:
动态绑定HTML属性:
html
<img :src="imageUrl" :alt="description">
<button :disabled="isProcessing">提交</button>
类绑定(特殊对象语法):
html
<div :class="{ 'active': isActive, 'error': hasError }">
样式绑定:
html
<div :style="{ color: textColor, fontSize: size + 'px' }">

Two-Way Binding with x-model

使用x-model双向绑定

Bind input values to data properties:
html
<input x-model="username" type="text">
<textarea x-model="message"></textarea>
<select x-model="country">
  <option value="us">United States</option>
  <option value="ca">Canada</option>
</select>
Modifiers:
  • .number
    - Convert to number
  • .debounce
    - Debounce input
  • .throttle
    - Throttle input
将输入值与数据属性绑定:
html
<input x-model="username" type="text">
<textarea x-model="message"></textarea>
<select x-model="country">
  <option value="us">美国</option>
  <option value="ca">加拿大</option>
</select>
修饰符:
  • .number
    - 转换为数字类型
  • .debounce
    - 输入防抖
  • .throttle
    - 输入节流

Common Patterns

常见模式

Toggle Component

切换组件

html
<div x-data="{ open: false }">
  <button @click="open = !open">Toggle</button>
  <div x-show="open" x-transition>
    Content to show/hide
  </div>
</div>
html
<div x-data="{ open: false }">
  <button @click="open = !open">切换</button>
  <div x-show="open" x-transition>
    显示/隐藏的内容
  </div>
</div>

Dropdown Component

下拉菜单组件

html
<div x-data="{ open: false }">
  <button @click="open = !open">Open Dropdown</button>
  <div x-show="open" @click.outside="open = false">
    <a href="#">Option 1</a>
    <a href="#">Option 2</a>
  </div>
</div>
html
<div x-data="{ open: false }">
  <button @click="open = !open">打开下拉菜单</button>
  <div x-show="open" @click.outside="open = false">
    <a href="#">选项1</a>
    <a href="#">选项2</a>
  </div>
</div>

Search/Filter List

搜索/筛选列表

html
<div x-data="{
  search: '',
  items: ['Apple', 'Banana', 'Cherry'],
  get filteredItems() {
    return this.items.filter(i => 
      i.toLowerCase().includes(this.search.toLowerCase())
    )
  }
}">
  <input x-model="search" placeholder="Search...">
  <template x-for="item in filteredItems" :key="item">
    <div x-text="item"></div>
  </template>
</div>
html
<div x-data="{
  search: '',
  items: ['苹果', '香蕉', '樱桃'],
  get filteredItems() {
    return this.items.filter(i => 
      i.toLowerCase().includes(this.search.toLowerCase())
    )
  }
}">
  <input x-model="search" placeholder="搜索...">
  <template x-for="item in filteredItems" :key="item">
    <div x-text="item"></div>
  </template>
</div>

Form with Validation

带验证的表单

html
<div x-data="{ 
  email: '', 
  get isValid() { 
    return this.email.includes('@') 
  } 
}">
  <input x-model="email" type="email">
  <button :disabled="!isValid">Submit</button>
  <span x-show="!isValid" class="error">Invalid email</span>
</div>
html
<div x-data="{ 
  email: '', 
  get isValid() { 
    return this.email.includes('@') 
  } 
}">
  <input x-model="email" type="email">
  <button :disabled="!isValid">提交</button>
  <span x-show="!isValid" class="error">邮箱无效</span>
</div>

Transitions

过渡效果

Add smooth transitions with
x-transition
:
Simple transition:
html
<div x-show="open" x-transition>
  Content with fade and scale transition
</div>
Custom duration:
html
<div x-show="open" x-transition.duration.500ms>
Separate in/out durations:
html
<div 
  x-show="open"
  x-transition:enter.duration.500ms
  x-transition:leave.duration.1000ms
>
Transition specific properties:
html
<div x-show="open" x-transition.opacity>
<div x-show="open" x-transition.scale>
使用
x-transition
添加平滑过渡:
简单过渡:
html
<div x-show="open" x-transition>
  带有淡入淡出和缩放过渡的内容
</div>
自定义时长:
html
<div x-show="open" x-transition.duration.500ms>
分开设置进入/退出时长:
html
<div 
  x-show="open"
  x-transition:enter.duration.500ms
  x-transition:leave.duration.1000ms
>
针对特定属性的过渡:
html
<div x-show="open" x-transition.opacity>
<div x-show="open" x-transition.scale>

Reusable Components

可复用组件

Define reusable component logic with
Alpine.data()
:
javascript
Alpine.data('dropdown', () => ({
  open: false,
  toggle() {
    this.open = !this.open
  },
  close() {
    this.open = false
  }
}))
Use in HTML:
html
<div x-data="dropdown">
  <button @click="toggle">Toggle</button>
  <div x-show="open" @click.outside="close">
    Dropdown content
  </div>
</div>
使用
Alpine.data()
定义可复用组件逻辑:
javascript
Alpine.data('dropdown', () => ({
  open: false,
  toggle() {
    this.open = !this.open
  },
  close() {
    this.open = false
  }
}))
在HTML中使用:
html
<div x-data="dropdown">
  <button @click="toggle">切换</button>
  <div x-show="open" @click.outside="close">
    下拉菜单内容
  </div>
</div>

Global State

全局状态

Share state across components using
Alpine.store()
:
javascript
Alpine.store('auth', {
  user: null,
  loggedIn: false,
  login(user) {
    this.user = user
    this.loggedIn = true
  }
})
Access in templates:
html
<div x-data>
  <span x-show="$store.auth.loggedIn" x-text="$store.auth.user"></span>
  <button @click="$store.auth.login('John')">Login</button>
</div>
使用
Alpine.store()
在组件间共享状态:
javascript
Alpine.store('auth', {
  user: null,
  loggedIn: false,
  login(user) {
    this.user = user
    this.loggedIn = true
  }
})
在模板中访问:
html
<div x-data>
  <span x-show="$store.auth.loggedIn" x-text="$store.auth.user"></span>
  <button @click="$store.auth.login('John')">登录</button>
</div>

Magic Properties

魔法属性

Alpine provides magic properties accessible anywhere:
  • $el
    - Reference to current DOM element
  • $refs
    - Access elements marked with
    x-ref
  • $store
    - Access global stores
  • $watch
    - Watch for data changes
  • $dispatch
    - Dispatch custom events
  • $nextTick
    - Execute after next DOM update
  • $root
    - Access root element of component
  • $data
    - Access entire data object
  • $id
    - Generate unique IDs
Example using $refs:
html
<div x-data>
  <input x-ref="emailInput" type="email">
  <button @click="$refs.emailInput.focus()">Focus Email</button>
</div>
Alpine提供可在任意位置访问的魔法属性:
  • $el
    - 当前DOM元素的引用
  • $refs
    - 访问标记有
    x-ref
    的元素
  • $store
    - 访问全局状态存储
  • $watch
    - 监听数据变更
  • $dispatch
    - 派发自定义事件
  • $nextTick
    - 在下一次DOM更新后执行
  • $root
    - 访问组件的根元素
  • $data
    - 访问完整的数据对象
  • $id
    - 生成唯一ID
使用$refs的示例:
html
<div x-data>
  <input x-ref="emailInput" type="email">
  <button @click="$refs.emailInput.focus()">聚焦邮箱输入框</button>
</div>

Best Practices

最佳实践

Keep data objects simple - Start with minimal state and add as needed:
html
<!-- Good -->
<div x-data="{ open: false }">

<!-- Avoid over-engineering -->
<div x-data="{ state: { ui: { modal: { open: false } } } }">
Use getters for computed values:
javascript
{
  items: [1, 2, 3],
  get total() {
    return this.items.reduce((sum, i) => sum + i, 0)
  }
}
Prevent FOUC (Flash of Unstyled Content) with
x-cloak
:
html
<style>
  [x-cloak] { display: none !important; }
</style>
<div x-data x-cloak>
  <!-- Content hidden until Alpine initializes -->
</div>
Extract complex logic to Alpine.data():
javascript
// Instead of inline in HTML
Alpine.data('complexForm', () => ({
  // Complex initialization and methods
}))
Use event modifiers appropriately:
html
<form @submit.prevent="handleSubmit">
<div @click.outside="close">
保持数据对象简洁 - 从最小状态开始,按需添加:
html
<!-- 推荐 -->
<div x-data="{ open: false }">

<!-- 避免过度设计 -->
<div x-data="{ state: { ui: { modal: { open: false } } } }">
使用getter处理计算值:
javascript
{
  items: [1, 2, 3],
  get total() {
    return this.items.reduce((sum, i) => sum + i, 0)
  }
}
使用
x-cloak
避免FOUC(未样式内容闪烁)
:
html
<style>
  [x-cloak] { display: none !important; }
</style>
<div x-data x-cloak>
  <!-- 内容在Alpine初始化前隐藏 -->
</div>
将复杂逻辑提取到Alpine.data()中:
javascript
// 替代在HTML中内联
Alpine.data('complexForm', () => ({
  // 复杂的初始化和方法
}))
合理使用事件修饰符:
html
<form @submit.prevent="handleSubmit">
<div @click.outside="close">

Common Gotchas

常见陷阱

x-for requires template element:
html
<!-- Wrong -->
<div x-for="item in items">

<!-- Correct -->
<template x-for="item in items">
  <div x-text="item"></div>
</template>
x-if also requires template:
html
<template x-if="condition">
  <div>Content</div>
</template>
Accessing parent scope - Use
this
when needed:
javascript
{
  items: ['a', 'b'],
  get filteredItems() {
    return this.items.filter(...)  // Must use this.items
  }
}
Script defer is important:
html
<!-- Ensures Alpine loads after DOM is ready -->
<script defer src="...alpine.min.js"></script>
x-for必须作用于template元素:
html
<!-- 错误 -->
<div x-for="item in items">

<!-- 正确 -->
<template x-for="item in items">
  <div x-text="item"></div>
</template>
x-if也需要template元素:
html
<template x-if="condition">
  <div>内容</div>
</template>
访问父作用域 - 必要时使用
this
:
javascript
{
  items: ['a', 'b'],
  get filteredItems() {
    return this.items.filter(...)  // 必须使用this.items
  }
}
脚本的defer属性很重要:
html
<!-- 确保Alpine在DOM准备好后加载 -->
<script defer src="...alpine.min.js"></script>

Quick Reference

速查表

DirectivePurposeExample
x-data
Define component state
<div x-data="{ count: 0 }">
x-text
Set text content
<span x-text="message">
x-html
Set HTML content
<div x-html="content">
x-show
Toggle visibility
<div x-show="isVisible">
x-if
Conditional rendering
<template x-if="show">
x-for
Loop over array
<template x-for="item in items">
x-on/@
Listen to events
<button @click="handler">
x-bind/:
Bind attributes
<img :src="url">
x-model
Two-way binding
<input x-model="value">
x-transition
Add transitions
<div x-show="open" x-transition>
指令用途示例
x-data
定义组件状态
<div x-data="{ count: 0 }">
x-text
设置文本内容
<span x-text="message">
x-html
设置HTML内容
<div x-html="content">
x-show
切换可见性
<div x-show="isVisible">
x-if
条件渲染
<template x-if="show">
x-for
遍历数组
<template x-for="item in items">
x-on/@
监听事件
<button @click="handler">
x-bind/:
绑定属性
<img :src="url">
x-model
双向绑定
<input x-model="value">
x-transition
添加过渡效果
<div x-show="open" x-transition>

Additional Resources

额外资源

For comprehensive directive documentation and advanced patterns:
  • references/directives-reference.md
    - Complete guide to all Alpine directives
  • references/advanced-patterns.md
    - Advanced component patterns and techniques
Official documentation: https://alpinejs.dev
如需完整的指令文档和高级模式:
  • references/directives-reference.md
    - 所有Alpine指令的完整指南
  • references/advanced-patterns.md
    - 高级组件模式与技巧
官方文档:https://alpinejs.dev