You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alpine.js实现表格动态加行时单次点击新增23行问题如何解决

Alpine.js 点击添加按钮重复新增行问题修复方案

问题根因

你的代码存在多个语法和结构错误,共同导致了单次点击触发多次新增逻辑:

  • 表格结构不规范:x-for循环内直接写<td>缺少<tr>行标签包裹,且大量标签未闭合,浏览器自动补全DOM时错误扩大了x-for的循环范围
  • 添加按钮被放在x-for循环模板内部,每次数组更新都会重复渲染按钮、重复绑定点击事件,触发时批量执行多次新增逻辑
  • x-model错误绑定到非表单元素<tbody>上,x-model仅支持input、textarea等表单输入组件
  • 组件返回的状态对象中存在多余逗号的语法错误,引发状态解析异常
  • <td>上绑定的x-text="services.length"会直接覆盖内部的<a>标签内容,导致按钮本身逻辑异常

修复步骤

  1. 修正表格DOM结构:x-for循环渲染<tr>行元素,每行内包裹对应<td>
  2. 将「点击添加」按钮移出x-for循环模板,避免重复绑定事件
  3. 移除<tbody>上的无效x-model绑定,将x-model绑定到对应服务内容的输入框上
  4. 删除状态对象中多余的语法逗号
  5. 补充缺失的标签闭合逻辑

修复后完整代码

<div class="mt-2" x-data="services()">
    <table>
        <tbody class="bg-gray-200" x-show="services.length">
            <template x-for="service in services" :key="service.id">
                <tr>
                    <!-- 序号列 -->
                    <td x-text="service.id"></td>
                    <!-- 服务内容输入列 -->
                    <td><input type="text" x-model="service.body"></td>
                    <!-- 删除按钮列 -->
                    <td><button @click="deleteService(service)">删除</button></td>
                </tr>
            </template>
        </tbody>
    </table>
    <!-- 添加按钮放在循环外部 -->
    <a @click="addService()" class="cursor-pointer">Click to add more</a>
</div>

<script>                                                    
function services() {
    return {                                                    
        services: [
            // 初始默认加载一行
            {
                id: 1,
                body: '',
                completed: false
            }
        ],
        newService: '',
        addService() {
            this.services.push({                                        
                id: this.services.length + 1,                           
                body: this.newService,                               
                completed: false                                        
            });                                                         
            this.newService = '';                                       
        },
        deleteService(service){                                     
            let position = this.services.indexOf(service);             
            this.services.splice(position, 1);
            // 删除后重新排序id,避免id混乱
            this.services.forEach((item, index) => {
                item.id = index + 1
            })
        }                                                           
    }                                                           
}                                                           
</script>

内容的提问来源于stack exchange,提问作者Zahra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:48:02