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

如何使用Alpine.js的x-for独立设置嵌套表格的单元格值

问题根因

你当前所有行的数据都共享根级别的fields和fields1数组,每次新增行时还会先清空这两个数组,导致所有行绑定的都是同一份数据源,自然会出现修改一行所有行同步变更的问题。正确的做法是把每行专属的fields、fields1数据存到对应的rows数组的每一项里,每行独立持有自己的数据源,互不干扰。


修正后的JS代码

function handler() {
  return {
    rows: [],
    // 初始化行ID计数
    id: 1,
    addRate(row) {
      row.fields1.push({
        value1: '',
        value2: '',
        value3: '',
        rType: '',
        typeA: '',
        value4: '',
        typeBDateFrom: '',
        typeBDateTo: ''
      });
    },
    listField() {
      // 每次新增行,创建独立的fields和fields1挂载到当前行对象
      const newRow = {
        id: this.id++,
        fields1: [],
        fields: []
      };
      // 给当前新行初始化fields1数据
      newRow.fields1.push({
        value1: '',
        value2: '',
        value3: '',
        rType: '',
        typeA: '',
        value4: '',
        typeBDateFrom: '',
        typeBDateTo: ''
      });
      // 给当前新行初始化fields数据
      newRow.fields.push({
        value5: '3',
        value6: '20',
        value7: 'DC',
        value8: '40',
        value9: '523',
        value10: '654',
        value11: 'TEST',
        value12: 'true',
        value13: 'Class1',
        value14: '5656',
        value15: 'TRM78799',
        id:'1'
      });
      this.rows.push(newRow);
    },
  }
};
function setDecimal(event) {
  event.target.value = parseFloat(event.target.value).toFixed(3);
};

修正后的HTML代码

仅需要把原来遍历全局fields1和fields的逻辑,改为从当前遍历的行对象中取对应数据即可,同时修复了原有HTML不符合表格规范、输入框类型错误等问题:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<div class="container col-md-10 offset-md-1">
  <div class="row" x-data="handler()" x-init="listField()">
    <div class="col">
      <table class="table align-items-center table-sm" style="text-align: center;">
        <tr>
          <template x-for="(row, rowIndex) in rows" :key="row.id">
            <td colspan="12">
              <p>
              <table class="table align-items-center table-sm table-bordered" style="text-align: center;">
                <tbody>
                  <!-- 从当前行对象取独立的fields1 -->
                  <template x-for="(field1, index) in row.fields1" :key="index">
                    <tr class="table-success">
                      <td style="width:100px;"><b>Type</b></td>
                      <td style="width:100px;">
                        <select x-model="field1.rType" class="custom-select" name="rType" required>
                          <option selected>---</option>
                          <option value="Type A">Type A</option>
                          <option value="Type B">Type B</option>
                        </select>
                      </td>
                      <td x-show="field1.rType==='Type A'" style="width:120px;">
                        <b>Type A Name</b>
                      </td>
                      <td x-show="field1.rType==='Type A'">
                        <input x-model="field1.typeA" type="text" class="form-control" name="typeA">
                      </td>
                      <td x-show="field1.rType==='Type A'" style="width:150px;">
                        <b>Value4</b>
                      </td>
                      <td x-show="field1.rType==='Type A'">
                        <input x-model="field1.value4" type="text" class="form-control" name="value4">
                      </td>
                      <td x-show="field1.rType==='Type B'" style="width:120px;">
                        <b>From</b>
                      </td>
                      <td x-show="field1.rType==='Type B'">
                        <input x-model="field1.typeBDateFrom" type="date" class="form-control" name="typeBDateFrom">
                      </td>
                      <td x-show="field1.rType==='Type B'" style="width:150px;">
                        <b>To</b>
                      </td>
                      <td x-show="field1.rType==='Type B'">
                        <input x-model="field1.typeBDateTo" type="date" class="form-control" name="typeBDateTo">
                      </td>
                    </tr>
                  </template>
                </tbody>
              </table>
              </p>
            <p>
            <table class="table align-items-center table-sm table-bordered" style="text-align: center;">
              <thead class="thead-dark">
                <tr>
                  <th>No</th>
                  <th style="width:20px;">Value5</th>
                  <th style="width:80px;">Value6</th>
                  <th style="width:150px;">Value7</th>
                  <th style="width:120px;">Value8</th>
                  <th style="width:120px;">Value9</th>
                  <th style="width:130px;">Value11</th>
                  <th style="width:180px;">Value12</th>
                  <th style="width:180px;">Value1</th>
                  <th style="width:180px;">Value2</th>
                  <th style="width:180px;">Value3</th>
                </tr>
              </thead>
              <tbody>
                <!-- 从当前行对象取独立的fields -->
                <template x-for="(field, index) in row.fields" :key="index">
                  <tr>
                    <td x-text="index + 1"></td>
                    <td x-text="field.value5"></td>
                    <td x-text="field.value6"></td>
                    <td>
                      <p x-text="field.value7"></p>
                      <p x-show="field.value7==='RFR' || field.value7==='RFRHC'">
                        <span x-text="field.value8"></span><span>&#x2103;</span>
                      </p>
                    </td>
                    <td x-text="field.value9"></td>
                    <td x-text="field.value10"></td>
                    <td x-text="field.value11"></td>
                    <td x-show="field.value12">
                      <p>
                        <label><b>Value13 </b><span x-text="field.value13"></span></label>
                      </p>
                      <p>
                        <label><b>Value14 </b><span x-text="field.value14"></span></label>
                      </p>
                    </td>
                    <td x-show="!field.value12"></td>
                    <td class="table-success">
                      <input x-model="field.value1" type="number" class="form-control"
                             @change="setDecimal" min="0" max="10000000" name="value1"
                             step="0.001" value="0.000" required>
                    </td>
                    <td class="table-success">
                      <select x-model="field.value2" class="custom-select" name="value2" required>
                        <option selected>---</option>
                        <option value="USD">USD</option>
                        <option value="EUR">EUR</option>
                      </select>
                    </td>
                    <td class="table-success">
                      <input x-model="field.value3" type="text" class="form-control" name="value3">
                    </td>
                  </tr>
                </template>
              </tbody>
            </table>
          </p>
          </td>
        </template>
      </tr>
    <tr>
      <td colspan="12" class="text-right"><button type="button" class="btn btn-info"
                                                  @click="listField()">+ Add Row</button></td>
    </tr>
    </table>
  </div>
  </div>
  </div>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>

其他附带修正

  • 修复了setDecimal函数的指向问题,原写法拿不到正确的输入框元素
  • 修正了原HTML里type="Type B"的错误输入框类型,改为标准的date类型
  • 修正了条件判断里的单竖线|为逻辑或||
  • 移除了重复的id属性,避免DOM id冲突
  • 行的key改为唯一的row.id,避免列表渲染异常
  • 原<template>外层直接包<p>不符合table结构,改为套<td colspan="12">符合HTML表格规范

内容的提问来源于stack exchange,提问作者Cem F. Çelebi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 07:06:04