道招

el-table搭配el-form实现数据校验

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

el-table搭配el-form实现数据校验

之前已经讲过一个关于el-form的校验的文章《 element-ui动态表单async-validate校验 please transfer a valid prop path to form item!》,表单的校验依然是async-validate实现的。 目前在项目中使用到的表格很多时候比表单还多,以前表格是自己写的校验,这样一般是在点击提交按钮时会触发校验,代码一般是这样的。
listData: [
          {
            salePriceErr: '',
            salePrice: 1,
            listPriceErr: '',
            listPrice: 2,
            courseErr: '',
            course: 'Math',
          },{
            salePriceErr: '',
            salePrice: 2,
            listPriceErr: '',
            listPrice: 8,
            courseErr: '',
            course: 'CS',
          }]
<el-table :data="listData">
  <el-table-column label="salePrice" prop="salePrice">
    <template slot-scope="scope">
      <el-input-number v-model="scope.row.salePrice"></el-input-number>
      <p v-if="scope.row.salePriceErr">{{scope.row.salePriceErr}}</p>
    </template>
  </el-table-column>
  <el-table-column label="listPrice" prop="listPrice">
    <template slot-scope="scope">
      <el-input-number v-model="scope.row.listPrice"></el-input-number>
      <p v-if="scope.row.listPriceErr">{{scope.row.listPriceErr}}</p>
    </template>
  </el-table-column>
  <el-table-column label="listPrice" prop="listPrice">
    <template slot-scope="scope">
      <el-button @click="save(scope)"></el-button>
    </template>
  </el-table-column>
</el-talbe>
这种我们一般在点击是在save方法里面先校验。这样的缺点很明显: 1. 我们需要预设一些字段,比如salePriceErr, listPriceErr等,这些字段后端肯定不会返回啊,我们在listData里面需要额外加上,并且我们一般需要使用$set来添加这些字段已确保它们是响应式的。并且这种事提前知道有salePrice或者listPrice字段的,如果有个数组,那样里面有多少字段也是无法预知的,就不好提前预设了。
listData: [
{
  salePrice: 1,
  listPrice: 2,
  course: 'Math',
  users: [
  {
    studentNO: '001',
    name: 'zhangsan',
    scores: 122
  }, {
    studentNO: '002',
    name: 'lisi',
    scores: 107
  }]
}, {
  salePrice: 2,
  listPrice: 5,
  course: 'English',
  users: [
  {
    studentNO: '001',
    name: 'zhangsan',
    scores: 87
  }, {
    studentNO: '002',
    name: 'lisi',
    scores: 97
  }]
}]
如果我们要校验users里面的信息就不好预设xxxErr
关于如何动态加载数组users里面的数据可以参考《el-table实现动态列el-table-column
  1. 我们的校验需要在用户点击了按钮之后才回触发save方法,如果校验出现了不合法输入的提示,不再次触发校验的话那些提示不会自动消失,用户体验不好。
如果能像表单校验的话就不存在上述问题。 我们可以试着把el-table和el-form结合起来使用(部分代码从简)
<el-form>
  <el-table :data="listData">
    <el-table-column label="salePrice" prop="salePrice">
      <template slot-scope="scope">
        <el-form-item>
          <el-input-number v-model="scope.row.salePrice"></el-input-number>
          <p v-if="scope.row.salePriceErr">{{scope.row.salePriceErr}}</p>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="listPrice" prop="listPrice">
      <template slot-scope="scope">
        <el-form-item>
          <el-button @click="save(scope)"></el-button>
        </el-form-item>
      </template>
    </el-table-column>
  </el-talbe>
</el-form>
使用过el-form校验的都知道,它有属性modelrules,其中model是对象、rules也是对象,每个el-form-item需要prop来配合。 所以我们可以"改装"下数据
model: {
  listData: [{
    salePrice: 1,
    listPrice: 2,
    course: 'Math',
  }]
},
<el-form :model="model">
  <el-table :data="model.listData">
  <el-table-column v-for="(item, index) in obj.listData[0].users">
      <template slot="header" slot-scope="scope">
        {{item.name}}
      </template>
      <template slot-scope="scope">
        <el-form-item :prop="'listData.' + scope.$index + '.users.' + index + '.scores'" :rules="rules.scores">
          <el-input-number v-model="item.scores"></el-input-number>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="salePrice" prop="salePrice" :rules="rules.salePrice">
      <template slot-scope="scope">
        <el-form-item>
          <el-input-number v-model="scope.row.salePrice"></el-input-number>
          <p v-if="scope.row.salePriceErr">{{scope.row.salePriceErr}}</p>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template slot-scope="scope">
        <el-form-item>
          <el-button @click="save(scope)"></el-button>
        </el-form-item>
      </template>
    </el-table-column>
  </el-table>
</el-form>
rules: {
  salePrice: {
    validator(rules, value, callback){
      if(value) {
        callback();
      }else {
        callback('不能为空')
      }
    }
  },
  scores: {
    validator(rules, value, callback){
      if(value) {
        callback();
      }else {
        callback('不能为空')
      }
    }
  },
}
这里的rules是直接用在el-form-item上面的,尤其是像scores这种,放在el-form-item上更加方便些 大家可能注意到prop上貌似写的比较复杂 这种写法主要是为了遵循async-validate的规则,代码如下:
function getPropByPath(obj, path, strict) {
  var tempObj = obj;
  path = path.replace(/\[(\w+)\]/g, '.$1');
  path = path.replace(/^\./, '');

  var keyArr = path.split('.');
  var i = 0;
  for (var len = keyArr.length; i < len - 1; ++i) {
    if (!tempObj && !strict) break;
    var key = keyArr[i];
    if (key in tempObj) {
      tempObj = tempObj[key];
    } else {
      if (strict) {
        throw new Error('please transfer a valid prop path to form item!');
      }
      break;
    }
  }
  return {
    o: tempObj,
    k: keyArr[i],
    v: tempObj ? tempObj[keyArr[i]] : null
  };
};
所以上面的:prop="'listData.' + scope.$index + '.users.' + index + '.scores'"就可以实际上获取到的就是 this.obj.listData[0].users[0].scores的值了,当然,里面[0]的0是会变的。
关于async-validate也可以参考element-ui动态表单async-validate校验 please transfer a valid prop path to form item!
算了,今天就写这么多吧,改天有时间再写。 对上面写的有疑问欢迎大家一起探讨。
更新时间:
上一篇:el-table实现动态列el-table-column下一篇:vue让select的下拉列表支持层级关系(tree)

相关文章

el-table实现动态列el-table-column

element-ui的官网有el-table实现自定义表头的demo,没错,实现动态列就是用的这个。 假设我们有个这样的添加动态列的需求:将班上的同学(人数不固定)的各科成绩根据姓名横向展示出来 阅读更多…

element-ui表单源码解析之el-form

表单时大家常用的,根据本站的百度统计后台显示来到道招网的程序很多都在关注 《element-ui动态表单async-validate校验 please transfer a valid prop p 阅读更多…

关注道招网公众帐号
道招开发者二群