Introduction

The prop property of the el-form-item component is not supported by the prop property of the el-form-item component

<template>
  <div id="app">
    <el-form label-width="100px" :model="ruleForm" :rules="rules">

      <el-form-item
        v-for="(item, index) in tableData"
        :key="item.id"
        :prop="'tableData.' + index + '.name'"
        :rules="rules.name"
      >
        <el-input v-model="item.name"></el-input>
      </el-form-item>

    </el-form>
  </div>
</template>

<script>
export default {
  name: "App".data() {
    return {
      ruleForm: {
        name: ' '
      },
      tableData: [{id: 1.name: "" },
        { id: 2.name: ""},].rules: {
        name: [{required: true.message: "Please enter an activity name".trigger: "blur".validator(rule, value, callback) {
              console.log("rule: ", rule);
              console.log("value: ", value); },},],},}; }};</script>

Copy the code

I didn’t see anything wrong at first glance, but the code actually reported an error. Can we see the error

First of all, it should be made clear that this is a warning, not an error, but it directly leads to the unexpected result of our code execution. Let’s analyze this error:

**Error in mounted hook** Please arrange a valid path for PropCopy the code

Mounted is not in my code, so why does it return an error? Second question, let’s provide a prop that works, but here we are clearly giving a prop that works. Finally checked the official website and baidu have not found a good solution, finally there is no way, can only go to look at the source of element-UI, the source link is as follows:

1. Find packages/form/ SRC /form-item.vueCopy the code

Mounted hook = Mounted hook = Mounted hook = Mounted hook = Mounted hookCopy the code
mounted() {
  if (this.prop) {
    this.dispatch('ElForm'.'el.form.addField'[this]); // Don't worry about this step

    let initialValue = this.fieldValue; Fieldvalue / /
    // Determine if fieldValue is an array and merge if it is
    if (Array.isArray(initialValue)) {
      initialValue = [].concat(initialValue);
    }
    // Define an initialValue attribute for this
    Object.defineProperty(this.'initialValue', {
      value: initialValue
    });

    this.addValidateEvents(); }}Copy the code

My first thought when I looked at this code was, well, that’s nothing, so I took a value and I assigned a value, and I looked at it for a while and I realized that one of the blind spots was this.fieldValue and here, what is this? I don’t know. Go check it out.

  computed: {
      fieldValue() {
        // 1. Get the model property of the current "form" (important here, remember this step)
        const model = this.form.model;
        if(! model || !this.prop) { return; }

        // 2. Get the current "form-item" prop property,
        Prop ="'tableData.' + index + '.name'"
        let path = this.prop;
        if (path.indexOf(':')! = = -1) {
          path = path.replace(/ :.'. ');
        }
        // 3. Pass model and path to the getPropByPath method
        return getPropByPath(model, path, true).v; }}Copy the code

The code goes to fieldValue, finds that this is a computed property (see the steps in the notes), and finds that it ultimately returns the result of the getPropByPath method, so let’s look at this method. We find that this method is a method under utils/util

When you first see this method, does it look familiar? The more it looks like a JS interview question

function getValue(obj, path) {... }const obj = { a: { b: { c: '1' } } }

getValue(obj, 'a.b.c'); / / 1

Copy the code

Have! Do you have any! Insert a key into a string and get the value of that key. Let’s see what element does.

Let tempObj = obj, who was obj the first time? Is it the this.form.model from above? So let’s see what’s the model that we’re transferring in our code

We just need to remember here that we are passing an object {name: } Path = re match, keyArr = [‘tableData’, 0, ‘name’]. This code will loop through keyArr

Let’s get this straight:

{name: '} ', key is tableData, key is in tempObj? , obviously false, so I just go else, throw new ErrorCopy the code

Element determines whether the path is valid or not by determining whether the key is in the model. If we know this principle, we just need to modify our code slightly.

All we need to do is move our tableData into ruleForm, and then we can look at the console and see that it doesn’t have an error.

conclusion

I thought about why Element is doing this, because in that context, Element can only use a key in obj to determine whether the value passed by prop is valid. If we do not put tableData in ruleForm, form-item mounted cannot retrieve this data. Therefore, it cannot determine the name of the tableData that is currently passed in, so it cannot use key in OBj.