插槽 el-input 数据双向 绑定失效 响应式更新失败

发布于:2025-09-16 ⋅ 阅读:(25) ⋅ 点赞:(0)

目录

1. 先实现赋值、页面渲染

2.  新增时:初始化独立状态,确保响应式。(可以直接跳到这儿看!)

3. 编辑时--渲染。通过将接口返回的remark值映射到inputValues ,并使用this.$set 确保响应式,(这样才能达到编辑时数据渲染且能修改的效果),​编辑


~~~~话多,用于自己给自己解释啦~~~~~ 可以直接跳到这儿去看哦--->2.  新增时:初始化独立状态,确保响应式。

1. 问题:通过map ,给数组a添加remark 字段。但是el-input 是插槽,且备注的数量要根批次号的数量一致,input 实时更新失败且没有渲染到页面上

2. 方法:定义一个新的变量,如inputValues,用它代替原数组中的remark 。

3. 原因:a 数组中原本没有remark 这个属性,所以当在map动态添加这个属性时,Vue 无法检测到这个新增属性的变化,所以导致没有实时更新(因为没有提前对 remark 进行响应式劫持)。

inputValues 能实时更新,是因为它是在data 定义,从一开始就在响应式系统中,它的任何修改(通过$set)都会被 Vue 实时检测到。而且,对 inputValues 的修改全程使用this.$set,这个方法会主动告知 Vue “某个属性 / 索引的值变了”,强制触发响应式更新机制,从而同步到页面。

4. 案例:

1. 先实现赋值、页面渲染

html 代码:

data 中定义 变量

 

在input事件中,给对应的 stockoutWorkDetailBatchVoList 数组中的备注赋值,如下图。

2.  新增时:初始化独立状态,确保响应式。

关键代码:

async onBatchSelect(val) {
 let batchList = val.list || [];
 let rowIndex = this.batchParams.rowIndex ?? 0; // 确保rowIndex有默认值
  // 重点1:响应式初始化,初始化当前行的inputValues数组(若不存在)
 if (!Array.isArray(this.inputValues[rowIndex])) {
    this.$set(this.inputValues, rowIndex, []); //可以强制 Vue 为 rowIndex 这个新属性添加响应式监听,确保后续对 this.inputValues[rowIndex] 的修改能被检测到
 }
  // 生成 stockOutWorkDetailBatchVoList 并同步inputValues
  let stockOutWorkDetailBatchVoList = batchList.map((item, index) => {
    const { batchNo, quantity, auxiliaryQuantity, inventoryTypeCode, inventoryTypeName, batchNoFieldInfo } = item;
    let batchPropertyList = [];
    if (batchNoFieldInfo) {
      batchPropertyList = batchNoFieldInfo.split(',').map((item) => {
        const list = item.split(':');
        return {
          label: list[0] || '',
          value: list[1] || ''
        };
      });
    }

    //  重点2:安全赋值,确保索引有效,解决数组索引更新的响应式盲区(强制触发响应式更新,告知 Vue “索引 index 的值已修改”,从而同步更新页面)
    this.$set(this.inputValues[rowIndex], index, ''); 
    
    return { 
     ...
      remark: '' // 初始化remark字段
    };
  });

  //  重点3:双重验证:确保所有批次都已在inputValues中初始化
  stockOutWorkDetailBatchVoList.forEach((item, indexBatch) => {
    if (indexBatch >= 0 && indexBatch < this.inputValues[rowIndex].length) {
      this.$set(this.inputValues[rowIndex], indexBatch, item.remark || '');
    }
  });
}

3. 编辑时--渲染。通过将接口返回的remark值映射到inputValues ,并使用this.$set 确保响应式,(这样才能达到编辑时数据渲染且能修改的效果),

关键代码:

getDetail(stockOutNo){

 this.inputValues={}先清空再赋值
 list.forEach((item, index) => {
   this.$set(this.inputValues, index, []); // 初始化当前行数组
   const batchVoList = item.stockOutWorkDetailBatchVoList || [];
        
   batchVoList.forEach((itemBatch, indexBatch) => {
       this.$set(this.inputValues[index], indexBatch, itemBatch.remark || '');
      });
   });
}