# 弹窗表单配置

TIP

表格中的弹出的表单是内置组件avue-form组件,配置属性可以参考FORM组件文档

# 默认值

配置value为字段默认值

<avue-crud :option="option" :data="data" ></avue-crud>

<script>
export default{
  data() {
    return {
      data: [],
      option: {
        height:100,
        column: [
          {
            label: '姓名',
            prop: 'name',
            value:'small'
          }
        ]
      }
    }
  }
}
</script>

Expand Copy

# 打开表单前

TIP

你可以在打开前和关闭前做一些逻辑操作,例如打开根据id请求数据,关闭根据id保存数据等

打开表单前会执行beforeOpen方法,相关返回的方法值可以判断表单当前打开的类型是新增还是编辑

<avue-crud
  :data="data"
  v-model="form"
  :before-open="beforeOpen"
  :option="option"
></avue-crud>
<script>
  export default {
    data() {
      return {
        form:{},
        data: [{
            name:'张三',
            sex:'男'
        }],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name'
            }, {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
    methods: {
      beforeOpen(done,type){
        this.$alert(`我是${type}`, {
          confirmButtonText: '确定',
          callback: action => {
            if(['view','edit'].includes(type)){
              // 查看和编辑逻辑
            }else{
              //新增逻辑
              this.form.name='初始化赋值'
            }
            done();
          }
        });
          
      }
    }
  };
</script>
Expand Copy

# 关闭表单前

关闭表单前会执行beforeClose方法,执行返回的done方法后才会彻底关闭表单

<avue-crud
  :data="data"
  v-model="form"
  :before-close="beforeClose"
  :option="option"
></avue-crud>
<script>
  export default {
    data() {
      return {
        form:{},
        data: [{
            name:'张三',
            sex:'男'
        }],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name'
            }, {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
    methods: {
      beforeClose(done,type){
        this.$confirm('确认关闭?')
          .then(_ => {
            done();
          })
          .catch(_ => {});
        
      }
    }
  };
</script>
Expand Copy

# 不关弹窗连续添加

TIP

源码中涉及自定义卡槽和按钮的操作方法可以下面介绍

利用这2个函数可以做不关弹窗连续添加的例子

<avue-crud
  ref="crud"
  :data="data"
  v-model="form"
  @row-save="rowSave"
  :before-open="beforeOpen"
  :before-close="beforeClose"
  :option="option"
>
<template slot-scope="{row,index}" slot="menuForm">
    <el-button type="primary"
                     icon="el-icon-check"
                     size="small"
                     plain
                     v-if="type=='add'"
                     @click="handleNext()"
                    >继续添加</el-button>
  </template>
</avue-crud>


<script>
  export default {
    data() {
      return {
        form:{},
        flag:false,
        type:'',
        data: [],
        option:{
          align:'center',
          menuAlign:'center',
          viewBtn:true,
          column:[
             {
              label:'姓名',
              prop:'name'
            }, {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
    methods: {
      handleNext(){
        this.flag=true;
        this.$refs.crud.rowSave()
      },
      rowSave(form,done,loading){
         this.data.push(this.deepClone(this.form))
         this.$message.success(JSON.stringify(this.form))
          if(this.flag){
            this.flag=false;
            loading()
            this.form.name="";
            this.form.sex="";
            return 
          }
          done()
      },
       beforeClose(done){
        this.flag=false;
        done()
      },
      beforeOpen(done,type){
        this.type=type;
        done()
          
      }
    }
  };
</script>
Expand Copy

# 表单按钮位置

TIP

2.3.3+



配置dialogMenuPosition属性值即可,默认为right

<el-radio-group v-model="direction">
  <el-radio label="left">居左</el-radio>
  <el-radio label="center">居中</el-radio>
  <el-radio label="right">居右</el-radio>
</el-radio-group>
<br/><br/>
<avue-crud :option="option" :data="list"></avue-crud>
<script>
export default {
  watch:{
    direction(value){
      this.option.dialogMenuPosition=value;
    }
  },
  data(){
    return {
      direction:'right',
      list:[{
        id:1,
        name:'张三',
        sex:12
      },{
        id:2,
        name:'李四',
        sex:12
      }],
      option:{
        dialogMenuPosition:'right',
        column:[{
          label:'id',
          prop:'id'
        },{
          label:'姓名',
          prop:'name'
        },{
          label:'年龄',
          prop:'sex'
        }]
      }
    }
  }
}
</script>

Expand Copy

# 打开表单方式

TIP

2.1.0+



配置dialogType为弹窗的方式,dialogDirection为弹窗的位置

<el-radio-group v-model="direction">
  <el-radio label="ltr">从左往右开</el-radio>
  <el-radio label="rtl">从右往左开</el-radio>
  <el-radio label="ttb">从上往下开</el-radio>
  <el-radio label="btt">从下往上开</el-radio>
</el-radio-group>
<br/><br/>
<avue-crud :option="option" :data="list"></avue-crud>
<script>
export default {
  watch:{
    direction(value){
      this.option.dialogDirection=value;
    }
  },
  data(){
    return {
      direction:'rtl',
      list:[{
        name:'张三',
        sex:12
      },{
        name:'李四',
        sex:12
      }],
      option:{
        dialogDirection:'rtl',
        dialogType:'drawer',
        column:[{
          label:'姓名',
          prop:'name'
        },{
          label:'年龄',
          prop:'sex'
        }]
      }
    }
  }
}
</script>

Expand Copy

# 防重提交

为了防止数据重复提交,加入了防重提交机制,rowSave方法和rowUpdate方法返回done用于关闭表单方法和loading用于关闭禁止的表单不关闭表单

<avue-crud :data="data" :option="option" @row-save="handleRowSave" @row-update="handleRowUpdate"></avue-crud>

<script>
export default {
    data() {
      return {
        data: [
          {
            name:'张三',
            sex:'男'
          }, {
            name:'李四',
            sex:'女'
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name'
            }, {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
    methods:{
      handleRowSave(row,done,loading){
        this.$message.success('1秒后关闭禁止表单')
        setTimeout(()=>{
          loading()
          this.$message.success('3秒后关闭表单')
        },1000)
        setTimeout(()=>{
            done()
        },3000)
      }, 
      handleRowUpdate(row,index,done,loading){
        this.$message.success('1秒后关闭禁止表单')
        setTimeout(()=>{
          loading()
          this.$message.success('3秒后关闭表单')
        },1000)
        setTimeout(()=>{
            done()
        },3000)
      }
    }
}
</script>
Expand Copy

# 标题字段宽度

labelWidth为标题的宽度,默认为110,可以配置到option下作用于全部,也可以单独配置每一项

<avue-crud :data="data" :option="option"></avue-crud>

<script>
export default {
    data() {
      return {
        data: [
          {
            name:'张三',
            sex:'男'
          }, {
            name:'李四',
            sex:'女'
          }
        ],
        option:{
          labelWidth:150,
          column:[
             {
              labelWidth:30,
              label:'姓名',
              prop:'name'

            }, {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      }
    }
}
</script>
Expand Copy

# 验证

配置验证字段的rules的数据对象

<avue-crud :data="data" :option="option"></avue-crud>

<script>
export default {
    data() {
      return {
        data: [
          {
            name:'张三',
            sex:'男'
          }, {
            name:'李四',
            sex:'女'
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name',
              rules: [{
                required: true,
                message: "请输入姓名",
                trigger: "blur"
              }]

            }, {
              label:'性别',
              prop:'sex',
              rules: [{
                required: true,
                message: "请输入性别",
                trigger: "blur"
              }]
            }
          ]
        },
      }
    }
}
</script>
Expand Copy

# 自定义验证

TIP

自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator (opens new window)

<avue-crud :data="data" v-model="obj" :option="option" @error="error"></avue-crud>

<script>
export default {
    data() {
      var validatePass = (rule, value, callback)=>{
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          callback();
        }
      };
      var validatePass2 = (rule, value, callback)=>  {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.obj.password) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        obj:{},
        data: [],
        option:{
          column:[ {
              label:'密码',
              prop:'password',
              rules: [{ required: true,validator: validatePass, trigger: 'blur' }]
            }, {
              label:'确认密码',
              prop:'oldpassword',
              rules: [{ required: true,validator: validatePass2, trigger: 'blur' }]
            } ]
        }
      };
    },
    methods: {
       error(err){
        this.$message.success('请查看控制台');
        console.log(err)
      }
    }
}
</script>
Expand Copy

# 组件对象

TIP

2.6.2+

打开表单的时候可以获取相关字段的ref对象

<avue-crud ref="crud" :data="data" :before-open="beforeOpen" :option="option"></avue-crud>

<script>
export default {
    data() {
      return {
        data:[{
          text:'测试数据'
        }],
        option:{
          labelWidth: 120,
          column: [{
              label: '测试框',
              prop: 'text',
          }]
        }
      };
    },
    methods:{
      beforeOpen(done){
        done()
         setTimeout(()=>{
          this.$message.success('查看控制台');
          console.log('text的ref对象')
          console.log(this.$refs.crud.getPropRef('text'))
        },0)
      }
    }
}
</script>
Expand Copy

# 字段不同状态

TIP

2.6.7+

disableddisplaydetail等字段在新增和编辑不同状态下,字段的不同状态展示

<avue-crud :data="data" :option="option" ></avue-crud>

<script>
export default {
    data() {
      return {
        data: [
          {
            name:'张三',
            sex:'男',
            grade:0
          }, {
            name:'李四',
            sex:'女',
            grade:1
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name',
              editDisabled:true
            }, {
              label:'性别',
              prop:'sex',
              editDisplay:false
            }, {
              label:'权限',
              prop:'grade',
              editDetail:true,
              addDisabled:true
            }, {
              label:'测试',
              prop:'test',
              addDisplay:false
            }
          ]
        },
      };
    }
}
</script>
Expand Copy

# 深结构绑定

TIP

2.6.11+

bing绑定深层次的结构对象,prop也是需要填写

<avue-crud :option="option" :data="data" v-model="form">
  <div slot-scope="{}" slot="bindForm">
    <el-button type="primary" size="small" @click="form.deep.deep.deep.value='改变deep.deep.deep.value值'">改变deep.deep.deep.value值</el-button>
    <el-button type="primary" size="small" @click="form.test='改变test值'">改变test值</el-button>
    </br></br>
    {{form}}
  </div>
</avue-crud>

<script>
export default{
  data() {
    return {
      form:{},
      data: [{ 
        deep:{
          deep:{
            deep:{
              value:'我是深结构'
            }
          }
        }
      }],
      option: {
        labelWidth: 120,
        column: [
          {
            label: '深结构',
            prop: 'test',
            bind:'deep.deep.deep.value'
          },{
            label: '',
            prop: 'bind',
            span:24,
            hide:true,
            formslot:true
          }
        ]
      }
    }
  }
}
</script>

Expand Copy

# 字段排序

TIP

2.6.16+

配置order的序号可以实现表单和表格字段不同的顺序

<avue-crud :data="data" :option="option" ></avue-crud>

<script>
export default {
    data() {
      return {
        data: [
          {
            name:'张三',
            sex:'男'
          }, {
            name:'李四',
            sex:'女'
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name'
            }, {
              label:'性别',
              prop:'sex',
              order:1
            }
          ]
        },
      };
    },
    methods: {
    }
}
</script>
Expand Copy

# 表单窗口拖拽

TIP

2.5.3+

TIP

同时已经将拖拽封装成指令,在el的原声dialog上添加v-dialogDrag即可拖拽

dialogDrag设置为true即可拖动表单

<avue-crud :data="data" :option="option"></avue-crud>
<script>
export default {
    data() {
      return {
        data: [
          {
            name:'张三',
            sex:true
          }, {
            name:'李四',
            sex:false
          }
        ],
        option:{
          dialogDrag:true,
          column:[
             {
              label:'姓名',
              prop:'name',
            }, {
              label:'性别',
              prop:'sex'
            }
          ]
        }
      }
    }
}
</script>


Expand Copy

# 改变结构配置

TIP

2.8.12+

<avue-crud :defaults.sync="defaults" v-model="form" :option="option"  :data="data"></avue-crud>
<script>
export default {
  data(){
    return {
       form:{},
       defaults:{},
       data:[{
          text1:0
       }],
       option:{
          column: [{
            label: '内容1',
            prop: 'text1',
            type:'radio', 
            dicData:[{
              label:'显示',
              value:0
            },{
              label:'隐藏',
              value:1,
            }]
          },{
            label: '内容2',
            prop: 'text2',
            display:true
          },{
            label: '内容3',
            prop: 'text3'
          }]
       }
    }
  },
  watch:{
    'form.text1'(val){
      if(val==0){
        this.defaults.text2.display=true
        this.defaults.text3.label='内容3'
      }else{
        this.defaults.text2.display=false
        this.defaults.text3.label='有没有发现我变了'
      }
    }
  }
}
</script>

Expand Copy

# 与其它字段交互

TIP

2.8.12+

<avue-crud :data="data" :option="option"  v-model="form"></avue-crud>
<script>
export default {
  data(){
    return {
       data:[{
          text1:0
        }],
       form:{},
       option:{
          column: [{
            label: '内容1',
            prop: 'text1',
            type:'radio', 
            dicData:[{
              label:'显示',
              value:0
            },{
              label:'隐藏',
              value:1,
            }],
            control:(val,form)=>{
              if(val===0){
                return {
                  text2:{
                    display:true
                  },
                  text3:{
                    label:'内容3'
                  }
                }
              }else{
                return {
                  text2:{
                    display:false
                  },
                  text3:{
                    label:'有没有发现我变了'
                  }
                }
              }
            },
          },{
            label: '内容2',
            prop: 'text2',
            display:true
          },{
            label: '内容3',
            prop: 'text3'
          }]
       }
    }
  }
}
</script>

Expand Copy

# 子表单

TIP

2.1.0+

TIP

这里子子表单只能用于简单的场景,复杂的场景参考父子表更加灵活

配置dynamicchildren字段即可,配置方法和crud组件一致,有rowAddrowDel回调函数,与crud组件的卡槽用法一致


<avue-crud :option="option" :data="data" v-model="form"></avue-crud>
<script>
export default {
  data() {
      return {
        form:{},
        data:[{
          input1:'张三',
          dynamic: [{
            input: 1,
            select: 1,
            radio: 1,
          }, {
            input: 2,
            select: 2,
            radio: 1,
          }]
        }],
        option:{
          labelWidth: 110,
          column: [{
            label: '输入框',
            prop: "input1",
            span:12,
            row: true
          },
          {
            label: '子表单',
            prop: 'dynamic',
            type: 'dynamic',
            span:24,
            children: {
              // type:'form',
              align: 'center',
              headerAlign: 'center',
              rowAdd:(done)=>{
                this.$message.success('新增回调');
                  done({
                    input:'默认值'
                  });
              },
              rowDel:(row,done)=>{
                this.$message.success('删除回调'+JSON.stringify(row));
                done();
              },
              column: [{
                width: 200,
                label: '输入框',
                prop: "input",
                formslot: true,
              }, {
                width: 200,
                label: '选择框',
                prop: "select",
                type: 'select',
                rules:[{
                  type:'number',
                  required:true,
                  message:'请选择选择框',
                }],
                dicData: [{
                  label: '测试1',
                  value: 1
                }, {
                  label: '测试2',
                  value: 2
                }]
              }, {
                width: 200,
                label: '多选',
                prop: "checkbox",
                type: 'checkbox',
                dicData: [{
                  label: '测试1',
                  value: 1
                }, {
                  label: '测试2',
                  value: 2
                }]
              }, {
                width: 200,
                label: '开关',
                prop: "switch",
                type: 'switch',
                dicData: [{
                  label: '测试1',
                  value: 1
                }, {
                  label: '测试2',
                  value: 2
                }]
              }, {
                width: 200,
                label: '数字框',
                prop: "number",
                type: 'number'
              }]
            }
          },
          ]
        }
      }
  }
}
</script>

Expand Copy

# 表单分组

 <avue-crud :option="option" v-model="obj" :data="data"></avue-crud>
<script>
let baseUrl = 'https://cli.avuejs.com/api/area'
export default {
    data() {
      return {
        obj: {
          name: '11'
        },
        data: [{
          name: '张三',
          sex:15,
          province: '110000',
          city: '110100',
          area: '110101',
          checkbox: ['110000']
        }],
        option: {
          column: [{
            label: '姓名',
            prop: 'name',
            display:false
           },
            {
            label: '年龄',
            prop: 'sex',
            display:false
          }],
          group: [
            {
              label: '用户信息',
              prop: 'jbxx',
              icon: 'el-icon-edit-outline',
              column: [
                {
                  label: '姓名',
                  prop: 'name'
                },
                 {
                  label: '年龄',
                  prop: 'sex'
                }
              ]
            }, {
              label: '退款申请',
              prop: 'tksq',
              icon: 'el-icon-view',
              column: [
                {
                  label: '省份',
                  prop: 'province',
                  type: 'select',
                  props: {
                    label: 'name',
                    value: 'code'
                  },
                  cascader: ['city'],
                  dicUrl: `${baseUrl}/getProvince`,
                  rules: [
                    {
                      required: true,
                      message: '请选择省份',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '城市',
                  prop: 'city',
                  type: 'select',
                  cascader: ['area'],
                  props: {
                    label: 'name',
                    value: 'code'
                  },
                  cascaderIndex: 0,
                  dicUrl: `${baseUrl}/getCity/{{key}}`,
                  rules: [
                    {
                      required: true,
                      message: '请选择城市',
                      trigger: 'blur'
                    }
                  ]
                },
                {
                  label: '地区',
                  prop: 'area',
                  type: 'select',
                  props: {
                    label: 'name',
                    value: 'code'
                  },
                  cascaderIndex: 0,
                  dicUrl: `${baseUrl}/getArea/{{key}}`,
                  rules: [
                    {
                      required: true,
                      message: '请选择地区',
                      trigger: 'blur'
                    }
                  ]
                }
              ]
            }
            , {
              label: '用户信息',
              prop: 'yhxxs',
              icon: 'el-icon-edit-outline',
              column: [
                {
                  label: '测试长度',
                  prop: 'len',
                  maxlength: 5,
                }, {
                  labelWidth: 120,
                  label: '测试自定义',
                  prop: 'names',
                  formslot: true
                }
              ]
            }
          ]
        }
      }
    }
}
</script>

Expand Copy

# 自定义表单

设置列的属性formslottrue,在卡槽中指定列的prop加上Form作为卡槽的名称

<avue-crud :data="data" :option="option" v-model="user">
  <template slot-scope="{type,disabled}" slot="nameForm">
      <el-tag v-if="type=='add'">新增</el-tag>
      <el-tag v-else-if="type=='edit'">修改</el-tag>
      <el-tag v-else-if="type=='view'">查看</el-tag>
      <el-tag>{{user.name?user.name:'暂时没有内容'}}</el-tag>
      <el-input :disabled="disabled" v-model="user.name"></el-input>
  </template>
</avue-crud>

<script>
export default {
 data() {
      return {
        user:{},
        data: [
          {
            name:'张三',
            sex:'男'
          }, {
            name:'李四',
            sex:'女'
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name',
              formslot:true,
              rules: [{
                required: true,
                message: "请输入姓名",
                trigger: "blur"
              }]
            },
            {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
  }
</script>
Expand Copy

# 自定义表单错误提示

设置列的属性errorslottrue,在卡槽中指定列的prop加上Error作为卡槽的名称,

<avue-crud :data="data" :option="option" >
   <template slot-scope="{error}" slot="nameError">
      <p style="color:green">自定义提示{{error}}</p>
  </template>
</avue-crud>

<script>
export default {
 data() {
      return {
        user:{},
        data: [
          {
            sex:'男'
          }, {
            sex:'女'
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name',
              errorslot:true,
              rules: [{
                required: true,
                message: "请输入姓名",
                trigger: "blur"
              }]
            },
            {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
  }
</script>
Expand Copy

# 自定义表单标题

设置列的属性labelslottrue,在卡槽中指定列的prop加上Label作为卡槽的名称,

<avue-crud :data="data" :option="option">
   <template slot-scope="scope" slot="nameLabel">
     <span>姓名&nbsp;&nbsp;</span>
     <el-tooltip class="item" effect="dark" content="文字提示" placement="top-start">
      <i class="el-icon-warning"></i>
    </el-tooltip>
  </template>
</avue-crud>

<script>
export default {
 data() {
      return {
        data: [
          {
            name:'张三',
            sex:'男'
          }, {
            name:'李四',
            sex:'女'
          }
        ],
        option:{
          column:[
             {
              label:'姓名',
              prop:'name',
              labelslot:true,
              rules: [{
                required: true,
                message: "请输入姓名",
                trigger: "blur"
              }]
            },
            {
              label:'性别',
              prop:'sex'
            }
          ]
        },
      };
    },
  }
</script>
Expand Copy
Last Updated: 5/10/2022, 10:37:37 AM