# 基础展示

TIP

此示例展示了pl-form的基础使用,基于配置式,代码量大大减少,同时表单校验也简单了许多,在配置比较繁琐不如模板清晰的时候,可使用slot用模板编写.如demo中活动时间这个表单项,此例还同时展示了表单校验的基础使用,对应仅做必填校验的项,直接给对应的表单项添加required属性即可

-
<template>
  <pl-form
      :form-items="formItems"
      v-model="form"
      label-position="right" label-suffix="" label-width="120px"
      :rules="rules"
      @submit="submit"
      class="form-demo-01"
      ref="form"
  >
    <template v-slot:date="{form,item}">
      <el-form-item label="活动时间" style="margin-bottom: 0;">
        <el-col :span="11">
          <el-form-item prop="date1">
            <pl-date v-model="form.date1" prop="date1" value-format="timestamp"></pl-date>
          </el-form-item>
        </el-col>
        <el-col class="line" :span="2" style="text-align:center;">-</el-col>
        <el-col :span="11">
          <el-form-item prop="date2">
            <pl-time v-model="form.date2" prop="date2" style="width: 100%;"></pl-time>
          </el-form-item>
        </el-col>
      </el-form-item>
    </template>
  </pl-form>
</template>

<script>
export default {
  name: 'form-demo-01',
  data () {
    return {
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
      }
    }
  },
  methods: {
    submit (val) {
      console.log(val)
      this.$message.success(`表单数据为:${JSON.stringify(val)}`)
    }
  },
  computed: {
    formItems () {
      return [
        { comp: 'input', label: '活动名称', prop: 'name', required: true, rules: this.nameRules },
        { comp: 'select', label: '活动区域', prop: 'region', options: this.regionOptions, required: true },
        { slotName: 'date' },
        { comp: 'switch', label: '即时配送', prop: 'delivery', required: true },
        {
          comp: 'checkbox',
          label: '活动性质',
          prop: 'type',
          options: [ '美食/餐厅线上活动', '地推活动', '线下主题活动', '单纯品牌曝光' ],
          required: true
        },
        { comp: 'radio', label: '特殊资源', prop: 'resource', options: [ '线上品牌商赞助', '线下场地免费' ], required: true },
        { comp: 'input', label: '说明', prop: 'desc', type: 'textarea', required: true }
      ]
    },
    regionOptions () {
      return [
        { label: '北京', value: 'beijing' },
        { label: '上海', value: 'shanghai' },
        { label: '广州', value: 'guangzhou' },
        { label: '深圳', value: 'shenzhen' }
      ]
    },
    nameRules () {
      return {
        name: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
        ]
      }
    },
    rules () {
      return {
        date1: { required: true, message: '请选择日期', trigger: 'blur' },
        date2: { required: true, message: '请选择时间', trigger: 'blur' }
      }
    }
  }
}
</script>

<style lang="stylus">
  .form-demo-01 {
    width: 460px;
    .el-input {
      width: 100%;
    }
  }
</style>
显示代码

# 栅格布局

-
<template>
  <pl-form label-position="right" label-suffix="" label-width="120px" v-model="form" :form-items="formItems"
           class="form-demo-02">
    <template v-slot:date="{form,item}">
      <el-form-item label="活动时间" class="form-demo-02-date-item">
        <el-col :span="11">
          <el-form-item prop="date1">
            <pl-date v-model="form.date1" prop="date1" value-format="timestamp"></pl-date>
          </el-form-item>
        </el-col>
        <el-col class="line" :span="2" style="text-align:center;">-</el-col>
        <el-col :span="11">
          <el-form-item prop="date2">
            <pl-time v-model="form.date2" prop="date2"></pl-time>
          </el-form-item>
        </el-col>
      </el-form-item>
    </template>
  </pl-form>
</template>

<script>
export default {
  name: 'form-demo-02',
  data () {
    return {
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
      }
    }
  },
  computed: {
    formItems () {
      return [
        {
          comp: 'grid',
          cols: [
            { span: 12, comp: 'pl-input', label: '活动名称', prop: 'name' },
            { span: 12, comp: 'pl-select', label: '活动区域', prop: 'region', options: this.regionOptions }
          ]
        },
        {
          comp: 'grid',
          cols: [
            { span: 12, slotName: 'date' },
            { span: 12, comp: 'pl-switch', label: '即时配送', prop: 'delivery' }
          ]
        },
        {
          comp: 'pl-checkbox',
          label: '活动性质',
          prop: 'type',
          options: [ '美食/餐厅线上活动', '地推活动', '线下主题活动', '单纯品牌曝光' ]
        },
        { comp: 'pl-radio', label: '特殊资源', prop: 'resource', options: [ '线上品牌商赞助', '线下场地免费' ] },
        {
          comp: 'grid',
          cols: [
            {
              span: 16, comp: 'pl-input', label: '说明', prop: 'desc', type: 'textarea',
              maxlength: 300,
              'show-word-limit': true
            }
          ]
        }
      ]
    },
    regionOptions () {
      return [
        { label: '北京', value: 'beijing' },
        { label: '上海', value: 'shanghai' },
        { label: '广州', value: 'guangzhou' },
        { label: '深圳', value: 'shenzhen' }
      ]
    }
  }
}
</script>

<style lang="stylus">
  .form-demo-02 {
    .el-input {
      width: 100%;
    }
    .el-select {
      width: 100%;
    }
  }
  .form-demo-02-date-item {
    .el-input {
      width: 100%;
    }
  }
</style>
显示代码

# 自定义校验

这个例子中展示了如何使用自定义验证规则来完成密码的二次验证。

<template>
  <pl-form label-width="120px" label-position="right" label-suffix="" :form-items="formItems" v-model="form" ref="form"
           @submit="submit"></pl-form>
</template>

<script>
export default {
  name: 'form-demo-03',
  data () {
    return {
      form: {
        name: '',
        tel: '',
        email: '',
        pass: '',
        checkPass: ''
      }
    }
  },
  methods: {
    submit (val) {
      this.$message.success(`表单数据为:${JSON.stringify(val)}`)
    },
    validatePass (rule, value, callback) {
      if (value === '') {
        callback(new Error('请输入密码'))
      } else {
        if (this.form.checkPass !== '') {
          this.$refs.form.validateField('checkPass')
        }
        callback()
      }
    },
    validatePass2 (rule, value, callback) {
      if (value === '') {
        callback(new Error('请再次输入密码'))
      } else if (value !== this.form.pass) {
        callback(new Error('两次输入密码不一致!'))
      } else {
        callback()
      }
    }
  },
  computed: {
    formItems () {
      return [
        { comp: 'input', label: '姓名', prop: 'name', required: true },
        { comp: 'input', label: '手机号', prop: 'tel', required: true, validation: 'tel' },
        {
          comp: 'input', label: '邮箱', prop: 'email',
          required: true,
          rules: { type: 'email', message: '请输入正确的邮箱地址', trigger: [ 'blur', 'change' ] }
        },
        {
          comp: 'input',
          label: '密码',
          prop: 'pass',
          required: true,
          rules: { validator: this.validatePass, trigger: 'blur' }
        },
        {
          comp: 'input',
          label: '确认密码',
          prop: 'checkPass',
          required: true,
          rules: { validator: this.validatePass2, trigger: 'blur' }
        }
      ]
    }
  }
}
</script>

<style scoped>

</style>
显示代码

form组件是对el-form的二次封装, 内置表单校验,将表单项弄成json配置式数组格式 el-form的所有属性都可以直接继承

# Attributes

参数 说明 类型 可选值 默认值
value/v-model 表单值 object -
form-items 表单项 array []

# formItems

参数 说明 类型 可选值 默认值
label el-form-item的label string -
prop el-form-item的prop string -
comp 需要渲染成的组件 string -
options 当comp为select/checkbox/radio的时候此属性有效 array -
required 表单校验的必填属性 boolean -
rules 表单项的rules属性,和required等校验项会合并 array/object -
attrs 表单项的其他属性(对应element组件的props选项) - -

# Events

事件名 描述 参数
confirm 点击了提交按钮通过表单校验后会触发,val为form内容 (fn:val)