alpinejs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAlpine.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 attribute ensures Alpine loads after the HTML is parsed.
defer在HTML的中添加脚本标签:
<head>html
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>deferVia npm
通过npm
bash
npm install alpinejsThen 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 directive. All Alpine components start with :
x-datax-datahtml
<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
使用指令声明响应式状态。所有Alpine组件都以开头:
x-datax-datahtml
<div x-data="{ count: 0, message: 'Hello' }">
<!-- 状态可在该元素及其子元素中访问 -->
</div>关键点:
- 以JavaScript对象形式定义数据
- 属性具备响应式 - 变更会触发UI更新
- 数据作用域限定在该元素及其子元素内
- 子元素可覆盖父元素的数据属性
Event Handling with x-on
使用x-on处理事件
Listen to browser events using or the shorthand:
x-on:@html
<button @click="count++">Increment</button>
<button x-on:click="count++">Increment (verbose)</button>Common event modifiers:
- - Prevent default behavior
.prevent - - Stop event propagation
.stop - - Trigger when clicking outside element
.outside - - Listen on window object
.window - - Debounce the handler
.debounce
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 when toggling frequently (keeps element in DOM)
x-show - Use when conditionally rendering expensive content
x-if
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的使用场景:
- 当需要频繁切换时使用(元素保留在DOM中)
x-show - 当需要条件渲染开销较大的内容时使用
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 element
<template> - Should include for proper tracking
:key
遍历数组渲染列表:
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 or shorthand:
x-bind::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' }">使用或简写动态绑定HTML属性:
x-bind::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:
- - Convert to number
.number - - Debounce input
.debounce - - Throttle input
.throttle
将输入值与数据属性绑定:
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-transitionSimple 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:
- - Reference to current DOM element
$el - - Access elements marked with
$refsx-ref - - Access global stores
$store - - Watch for data changes
$watch - - Dispatch custom events
$dispatch - - Execute after next DOM update
$nextTick - - Access root element of component
$root - - Access entire data object
$data - - Generate unique IDs
$id
Example using $refs:
html
<div x-data>
<input x-ref="emailInput" type="email">
<button @click="$refs.emailInput.focus()">Focus Email</button>
</div>Alpine提供可在任意位置访问的魔法属性:
- - 当前DOM元素的引用
$el - - 访问标记有
$refs的元素x-ref - - 访问全局状态存储
$store - - 监听数据变更
$watch - - 派发自定义事件
$dispatch - - 在下一次DOM更新后执行
$nextTick - - 访问组件的根元素
$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-cloakhtml
<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)
}
}使用避免FOUC(未样式内容闪烁):
x-cloakhtml
<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 when needed:
thisjavascript
{
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>访问父作用域 - 必要时使用:
thisjavascript
{
items: ['a', 'b'],
get filteredItems() {
return this.items.filter(...) // 必须使用this.items
}
}脚本的defer属性很重要:
html
<!-- 确保Alpine在DOM准备好后加载 -->
<script defer src="...alpine.min.js"></script>Quick Reference
速查表
| Directive | Purpose | Example |
|---|---|---|
| Define component state | |
| Set text content | |
| Set HTML content | |
| Toggle visibility | |
| Conditional rendering | |
| Loop over array | |
| Listen to events | |
| Bind attributes | |
| Two-way binding | |
| Add transitions | |
| 指令 | 用途 | 示例 |
|---|---|---|
| 定义组件状态 | |
| 设置文本内容 | |
| 设置HTML内容 | |
| 切换可见性 | |
| 条件渲染 | |
| 遍历数组 | |
| 监听事件 | |
| 绑定属性 | |
| 双向绑定 | |
| 添加过渡效果 | |
Additional Resources
额外资源
For comprehensive directive documentation and advanced patterns:
- - Complete guide to all Alpine directives
references/directives-reference.md - - Advanced component patterns and techniques
references/advanced-patterns.md
Official documentation: https://alpinejs.dev
如需完整的指令文档和高级模式:
- - 所有Alpine指令的完整指南
references/directives-reference.md - - 高级组件模式与技巧
references/advanced-patterns.md
官方文档:https://alpinejs.dev