相关文章推荐
打酱油的啄木鸟  ·  如何循环生成Element中的标签控件-百度经验·  3 周前    · 
重情义的炒粉  ·  沈阳建设国家中心城市行动纲要-专项规划-沈阳 ...·  8 月前    · 
俊逸的杯子  ·  基隆市英語資源中心·  1 年前    · 
八块腹肌的小刀  ·  AS YOU ARE, 势随我动 ...·  2 年前    · 
飘逸的饼干  ·  clean master app for ...·  2 年前    · 
成熟的小刀  ·  岚图汽车2022年9月销量2519辆 ...·  2 年前    · 
Code  ›  vue + element 动态渲染、移除表单并添加验证开发者社区
vue input 表单验证 element
https://cloud.tencent.com/developer/article/1383535
活泼的茶壶
2 年前
作者头像
Krry
0 篇文章

vue + element 动态渲染、移除表单并添加验证

原创
前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > Krryblog > 正文

vue + element 动态渲染、移除表单并添加验证

原创
修改 于 2019-03-01 17:31:07
4.6K 0
举报

博客地址: https://ainyi.com/66

又接到新需求了吧~~

背景

在一个大表单里,有可能会出现这种需求,用户可以自己操作动态添加、移除表单,更加个性化的效果。

常见于填写个人信息、附加内容的表单

例如:

“工作经历”可以用户自己点击继续添加按钮,在原有的表单后面 append 多一个表单,不需要就点击右上方 X 按钮移除

问题

在实现之前,提出几个问题

  1. vue 怎么动态渲染或移除表单上去
  2. v-model 怎么绑定动态添加表单的 value 值
  3. 动态新增的表单如何验证
  4. 动态表单怎么填写对应的 prop

...

好吧,我当时也思考了一会,最后选择数组方式,动态渲染

代码实现讲解

利用数组,v-for 循环方式,可以完美实现动态渲染和移除,因为操作的只有对象数组而已

请格外注意动态添加表单的 rule 和 prop

每个动态添加的表单都要加上 rule

prop 需要根据对象数组下标绑定设置对应的 value(:prop="'azList' + index + '.azName'")

<div class="section-form" v-for="(item, index) in form.azList" :key="index"> 
  <span v-if="isShowCloseBtn" class="close" @click="deleteItem(index)">
    <i class="el-icon-close"></i>
  </span> 
  <el-form-item label="可用区名称:"
    :rules="[{ required: true, message: '可用区名称不能为空' }]"
    :prop="'azList[' + index + '].azName'"
    label-width="150px"> 
    <el-input placeholder="请输入可用区名称" v-model="item.azName" :maxlength="30"></el-input> 
  </el-form-item> 
  <el-form-item label="逻辑可用区编码:"
    :rules="[{ required: true, message: '逻辑可用区编码不能为空' }]"
    label-width="150px"
    :prop="'azList[' + index + '].logicCode'"> 
    <el-input placeholder="请输入唯一ID" v-model="item.logicCode" :maxlength="30"></el-input> 
  </el-form-item> 
  <el-form-item label="物理可用区编码:"
    :rules="[{ required: true, message: '物理可用区编码不能为空' }]"
    label-width="150px"
    :prop="'azList[' + index + '].physicCode'"> 
    <el-input placeholder="请输入唯一ID" v-model="item.physicCode" :maxlength="30"></el-input> 
  </el-form-item>
</div>

那么对应的 js 代码为

export default {
  name: 'vouchersDetail',
  data() {
    return {
      form: {
        regionName: '',
        regionCode: '',
	// 动态添加的对象数组
        azList: [
            azName: '',
            logicCode: '',
            physicCode: ''
  computed: {
    // 至少保留一个动态表单的开关
    isShowCloseBtn() {
      return this.form['azList'].length > 1
  methods: {
    addItem() {
      // 点击添加表单的按钮,只需要将表单绑定的 value 作为对象 push 到对象数组
      this.form['azList'].push({
        azName: '',
        logicCode: '',
        physicCode: '',
        weight: ''
    deleteItem(index) {
      // 点击移除表单的按钮,根据点击的当前 index 移除对象数组的元素
      this.form['azList'].splice(index, 1)
    goBack() {
      window.history.back(-1)
}

更新

19号更新,分离组件方法,写法更简便,易维护,还可以将校验规则剥离出去

根据上面的方法 ==利用数组,v-for 循环方式==

此次更新,关键在于,是父组件引用子组件的 ==template 循环==

v-for 循环数组的 item 对象传入子组件 template

每个子组件的 form 的 :model = 传入的 item,也就不需要用到数组下标 index,每个子组件是独立的一个 form,也就是说,每个动态添加字段的校验规则可以剥离出去了

父组件

template 循环<create-region class="section-form" ref="refCreateAz" :infoData="item" :indexNum="index" :isShowCloseBtn="isShowCloseBtn" v-for="(item, index) in form.azList" :key="index" @deleteItem="deleteItem"> </create-region>

js 与原来无差,只是多了引入子组件的 component

components: {
  CreateRegion: () => import('@/views/region/models/CreateRegion')
}

子组件

<template>
  <el-form :model="infoData" :rules="rulesAz" label-width="150px" ref="formAz">
    <span v-if="isShowCloseBtn" class="close" @click="deleteItem">
      <i class="el-icon-close"></i>
    </span>
    <el-form-item label="可用区名称:" prop="azName" label-width="150px">
      <el-input placeholder="请输入可用区名称" v-model="infoData.azName" :maxlength="30"></el-input>
    </el-form-item>
    <el-form-item label="逻辑可用区编码:" label-width="150px" prop="logicCode">
      <el-input placeholder="请输入唯一ID" v-model="infoData.logicCode" :maxlength="30"></el-input>
    </el-form-item>
    <el-form-item label="物理可用区编码:" label-width="150px" prop="physicCode">
      <el-input placeholder="请输入唯一ID" v-model="infoData.physicCode" :maxlength="30"></el-input>
    </el-form-item>
    <el-form-item label="权重设置:" label-width="150px">
      <el-input placeholder="请设置权重" v-model="infoData.weight"></el-input>
    </el-form-item>
  </el-form>
</template>
<script>
import { ORGION_AZLIST_RULES } from '@/views/service/rules'
export default {
  props: {
    infoData: {
      require: true
    indexNum: {
      type: Number
    isShowCloseBtn: {
      type: Boolean
  data() {
    return {
      form: this.infoData,
      rulesAz: ORGION_AZLIST_RULES.call(this)
  computed: {},
  methods: {
    deleteItem() {
      this.$emit('deleteItem', this.indexNum)
    validates() {
      return new Promise((resolve, reject) => {
        this.$refs['formAz'].validate(async valid => {
          if (valid) {
            // 验证通过
            resolve(true)
          } else {
            reject(false)
</script>

校验

export const ORGION_AZLIST_RULES = function() {
  return {
    logicCode: [
        required: true,
        message: '逻辑可用区编码不能为空',
        trigger: 'blur'
        validator: CHECK_AZEXITS_CODE.bind(this),
        trigger: 'blur'
    physicCode: [
        required: true,
        message: '物理可用区编码不能为空',
        trigger: 'blur'
        validator: CHECK_AZEXITS_CODE.bind(this),
        trigger: 'blur'
    azName: [
        required: true,
        message: '可用区名称不能为空',
        trigger: 'blur'
}

自定义校验

export const CHECK_AZEXITS_CODE = async function(rule, value, callback) {
  let paramName = rule.field
  let reqData = {}
  reqData[paramName] = value
  let { result } = await getAzExist(reqData)
  if (result.result) {
    if (paramName === 'logicCode') {
      callback(new Error('逻辑可用区编码已存在,请重新输入'))
    } else {
 
推荐文章
打酱油的啄木鸟  ·  如何循环生成Element中的标签控件-百度经验
3 周前
重情义的炒粉  ·  沈阳建设国家中心城市行动纲要-专项规划-沈阳市人民政府
8 月前
俊逸的杯子  ·  基隆市英語資源中心
1 年前
八块腹肌的小刀  ·  AS YOU ARE, 势随我动 吉利星越高阶运动SUV 驭势登临_车展动态 - 车主之家
2 年前
飘逸的饼干  ·  clean master app for firestick-掘金
2 年前
成熟的小刀  ·  岚图汽车2022年9月销量2519辆 同比上涨177%_平行线车网
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号