mcpField
A
alpinejs

alpinejs

github.com/brettatoms开发3257 次安装11 周前更新
代码仓库

关于 alpinejs

为使用 AlpineJS 的开发者整理的实践指南,涵盖指令、魔法属性和组件组织方式。重点是保持 HTML 属性简短,并将复杂逻辑提取到函数、可复用组件或全局 Store 中。

主要功能

  1. 01AlpineJS 指令速查
  2. 02魔法属性说明
  3. 03复杂逻辑提取建议
  4. 04可复用组件与全局 Store 模式
  5. 05表单验证与事件修饰符示例

适用场景

  1. 01整理包含复杂逻辑的 AlpineJS 页面
  2. 02在多个页面复用组件
  3. 03管理共享状态或表单交互

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/brettatoms/agent-skills --skill alpinejs

安装后在 Claude Code 中输入/alpinejs确认已加载。

详细介绍

AlpineJS 最佳实践

黄金法则:保持属性简短

绝不要在 HTML 属性中编写复杂逻辑。如果你的 x-data、x-init 或任何指令超过约 50 个字符,请将其提取出来。

指令速查表

指令用途示例
x-data声明响应式组件状态x-data="{ open: false }"
x-init在组件初始化时运行代码x-init="fetchData()"
x-show切换可见性(CSS display)x-show="open"
x-if条件渲染(必须包裹 <template>)<template x-if="show">
x-for循环(必须包裹 <template>)<template x-for="item in items">
x-bind: / :将属性绑定到表达式:class="{ active: isActive }"
x-on: / @监听事件@click="open = !open"
x-model对表单输入进行双向绑定x-model="email"
x-text设置文本内容x-text="message"
x-html设置内部 HTMLx-html="htmlContent"
x-ref通过 $refs 引用元素x-ref="input"
x-cloak在 Alpine 初始化前隐藏元素x-cloak(添加 CSS:[x-cloak] { display: none; })
x-transition应用进入/离开过渡效果x-transition 或 x-transition.duration.300ms
x-effect运行响应式副作用x-effect="console.log(count)"
x-ignore跳过 Alpine 初始化x-ignore
x-teleport将元素移动到其他位置x-teleport="#modals"
x-modelable暴露属性以供外部绑定x-modelable="value"

魔法属性

属性说明
$el当前 DOM 元素
$refs访问带有 x-ref 的元素
$store访问全局 Alpine 存储
$watch监听属性变化
$dispatch派发自定义事件
$nextTick在 DOM 更新后运行
$root组件的根元素
$data访问组件数据对象
$id生成唯一 ID

模式

❌ 错误:冗长的内联 JavaScript

<div x-data="{ items: [], loading: true, error: null, async fetchItems() { this.loading = true; try { const res = await fetch('/api/items'); this.items = await res.json(); } catch (e) { this.error = e.message; } finally { this.loading = false; } } }" x-init="fetchItems()">
✅ 正确:提取为函数
<script>
function itemList() {
  return {
    items: [],
    loading: true,
    error: null,
    
    async fetchItems() {
      this.loading = true;
      try {
        const res = await fetch('/api/items');
        this.items = await res.json();
      } catch (e) {
        this.error = e.message;
      } finally {
        this.loading = false;
      }
    }
  };
}
</script>

<div x-data="itemList()" x-init="fetchItems()">
  
</div>
✅ 正确:简单的内联状态

<div x-data="{ open: false, count: 0 }">
  <button @click="open = !open">Toggle</button>
  <div x-show="open" x-transition>Content</div>
</div>
✅ 正确:使用全局存储共享状态
<script>
document.addEventListener('alpine:init', () => {
  Alpine.store('cart', {
    items: [],
    add(item) { this.items.push(item); },
    get total() { return this.items.reduce((sum, i) => sum + i.price, 0); }
  });
});
</script>

<div x-data>
  <span x-text="$store.cart.total"></span>
</div>
✅ 正确:使用 Alpine.data() 创建可复用组件
<script>
document.addEventListener('alpine:init', () => {
  Alpine.data('dropdown', () => ({
    open: false,
    toggle() { this.open = !this.open; },
    close() { this.open = false; }
  }));
});
</script>

<div x-data="dropdown" @click.outside="close()">
  <button @click="toggle()">Menu</button>
  <ul x-show="open" x-transition>
    <li>Item 1</li>
  </ul>
</div>
✅ 正确:带验证的表单
<script>
function contactForm() {
  return {
    email: '',
    message: '',
    errors: {},
    
    validate() {
      this.errors = {};
      if (!this.email.includes('@')) this.errors.email = 'Invalid email';
      if (this.message.length < 10) this.errors.message = 'Too short';
      return Object.keys(this.errors).length === 0;
    },
    
    submit() {
      if (this.validate()) {
        // submit logic
      }
    }
  };
}
</script>

<form x-data="contactForm()" @submit.prevent="submit()">
  <input x-model="email" type="email">
  <span x-show="errors.email" x-text="errors.email" class="error"></span>
  
  <textarea x-model="message"></textarea>
  <span x-show="errors.message" x-text="errors.message" class="error"></span>
  
  <button type="submit">Send</button>
</form>
事件修饰符
@click.prevent     
@click.stop        
@click.outside     
@click.window      
@click.document    
@click.once        
@click.debounce    
@click.throttle    
@keydown.enter     
@keydown.escape    
过渡修饰符
x-transition                           
x-transition.duration.300ms            
x-transition.opacity                   
x-transition.scale.90                  
x-transition:enter.duration.500ms      
x-transition:leave.duration.200ms      

快速决策指南

  1. 状态只有 1–3 个简单属性? → 内联 x-data="{ open: false }"
  2. 包含方法或复杂逻辑? → 提取为 function componentName() { return {...} }
  3. 在多个页面重复使用? → 使用 Alpine.data('name', () => ({...}))
  4. 需要共享全局状态? → 使用 Alpine.store('name', {...})
  5. 属性字符串太长? → 这样做不对。把它提取出来。

评论

支持 Markdown