填充错误时 v-if span 不显示 vuejs

v-if span not displaying when errors are filled vuejs

所以我在数据中有一个错误数组,每当用户关注输入时,它都会检查它是否为空。如果它是空的,它会像这样向错误数组添加一个对象:

[
    "0": {
        "product_name": {
            "message": "to polje je obvezno"
        },
        "barcode": {
            "message": "to polje je obvezno"
        }
    },
    "1": {
        "barcode": {
            "message": "to polje je obvezno"
        }
    },
    "2": {
        "product_name": {
            "message": "to polje je obvezno"
        }
    }
]

所以 0,1,2 代表项目的索引,因为我有一个 v-for 循环,然后 product_name 或条形码代表 item/index 中的输入。(组件在 post 的末尾,如果你需要的话)。所以现在我试图在 product_name 或条形码存在时显示错误。

我正在这样尝试:

<span class="tooltip" 
      v-if="errors && errors[index] && errors[index]['product_name']" style="left: 5px">
  test123 (this is product_name error, above index is the current index in v-for so 0 or 1 or 2...)
</span>

<span class="tooltip" 
      v-if="errors && errors[index] && errors[index]['product_name']"style="left: 5px">
  test123 (this is barcode error, above index is the current index in v-for so 0 or 1 or 2...)
</span>

但不显示跨度

组件:

<tr v-for="(item, index) in documentItems" :key="item.id">
  <td>{{index + 1}}.</td>
  <td>
    <div>
      <textarea v-model="item.barcode"
                @focusout="checkInput('barcode',index)"
                cols="15" rows="2"> 
      </textarea>
      <span v-if="errors && errors[index] && errors[index]['barcode']">
        test123
      </span>
    </div>
  </td>
  <td>
    <div>
      <textarea v-model="item.product_name"
                @focusout="checkInput('product_name',index)"
                cols="15" rows="2"> 
      </textarea>
      <span v-if="errors && errors[index] && errors[index]['product_name']">
        test123
      </span>
    </div>
  </td>
</tr>

编辑:有没有可能是我的 checkInput 出了问题?这就是我创建错误的方式:

   checkInput(name, itemIndex){
        if(this.documentItems[itemIndex][name] == null){
            this.errors[itemIndex][name] = { message: 'to polje je obvezno'}
        };
        //testing
        console.log(this.errors[itemIndex][name]); //works
        if(this.errors[1]['product_name']){
            console.log("yes"); //works
        }
    },

编辑 2:

如果我这样定义错误对象,跨度会显示:

        errors: {
            0: {
                barcode: '',
                product_name: ''
            },
            1: {
                barcode: '',
                product_name: ''
            }
        },

但是如果我使用 for 循环执行此操作,跨度不会显示(我在方法中创建了一个 for 循环,在该方法中检索所有 documentItems 并在 mounted() 上触发):

for(var i = 0;i < response.data.documentItems[0].length;i++){
  this.errors[i] = {
    barcode: '',
    product_name: '',
  }
}

你的问题根源于他们文档中提到的 vue 反应性警告。

https://vuejs.org/v2/guide/reactivity.html#For-Objects

当您使用 this.foo = bar 手动添加字段时,Vue 将在任何运行之前为数据函数中定义的每个字段创建类似代理的对象(一种类似于使用 Object.defineProperty 的观察者的模式) (或类似的东西),如果 'foo' 键在您的数据字段中尚不可用,vue 不会使其具有反应性,因此它不会在您的 DOM 更改时更新它。

您可以通过几个解决方法实现您想要的。

他们的文档中也提到的第一种方法是使用 Object.assign 创建整个错误对象或传播语法并重新分配数据中的字段。

// instead of `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

此解决方案类似于将字段视为其不可变

所以您可以通过以下更改修复您的 checkInput 方法:

   checkInput(name, itemIndex){
        if(this.documentItems[itemIndex][name] == null){
            const newErrorForName = { [name]: { message: 'to polje je obvenzo' }};
                this.errors = Object.assign({}, {...this.errors, [itemIndex]: newErrorForName })
        };
        //testing
        console.log(this.errors[itemIndex][name]); //works
        if(this.errors[1]['product_name']){
            console.log("yes"); //works
        }
    },

这是因为vue无法理解手动对象属性 add/delete.

第二种方法是使用数组代替对象来表示错误。 这可能是一个更好的主意,因为您的错误对象实际上是一个数组。 它有固定的基于零的整数索引!