Achieve ELement-UI in the form of Form

Going deep into the science, we must create their own wheels, then we achieve the realization of Element-ui in the form of a manual form

1, using the form component

<template>
  <div class="form-index">
    <k-form :model="ruleForm" :rules="rules" ref="form">
      <k-form-item label="用户名" prop="username">
        <k-input v-model="ruleForm.username" placeholder="请输入用户名"></k-input>
      </k-form-item>
      <k-form-item label="密码" prop="password">
         <k-input v-model="ruleForm.password" type="password" placeholder="请输入密码"></k-input>
      </k-form-item>
      <k-form-item>
        <button @click="submitForm">login</button>
      </k-form-item>
    </k-form>
  </div>
</template>

<script>
import KForm from './KForm'
import KFormItem from './KFormItem'
import KInput from './KInput'
export default {
  name: 'kFormIndex',
  data () {
    return {
      ruleForm: {
        username: '',
        password: ''
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ]
      }
    }
  },
  components: {
    KForm,
    KFormItem,
    KInput
  },
  methods: {
    submitForm () {
      this.$refs.form.validate(result => {
        if (result) {
          alert('success')
        } else {
          alert('failure')
        }
      })
    }
  }
}
</script>

By the above code, we can see that, using a form assembly is a three-layer structure. And verifies the rule data rulesand form data modelin an outermost layer k-formon the form, because of the k-form-itemneed to use rulesand modeldefined in the outermost component, subassembly easy to use
Here Insert Picture Description
the relationship between the figure can clearly display assembly, and, through slotthe slot to build relationships between components, then we look to achieve the various components

k-input component

<template>
  <div>
    <input v-bind="$attrs" :value="value" @input="inputHandle">
  </div>
</template>

<script>
export default {
  inheritAttrs: false, //默认继承的属性去掉
  name: 'kInput',
  props: {
    value: {
      type: String
    }
  },
  methods: {
    inputHandle (e) {
      this.$emit('input', e.target.value)
      // 分发检验事件
      this.$parent.$emit('validate')
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

  • By the effect of form component, you can see k-inputtwo-way data binding implementation. Used in the outer layer v-modelis actually a syntactic sugar (to bind valueand listen for inputevents), in k-inputassembly, we need to accept propand distribute inputevents to implement two-way data binding.
  • $attrsCan get the value from the parent component pass over, and expand on the current label.
  • this.$parent.$emit('validate')Each inputvalue input box is changed need to be verified, since the parent components are used in slotthe slot, the use within parent components this.$on('validate', this.validate)for monitoring.

k-form-item

<template>
  <div>
    <span v-if="label">{{ label }}</span>
    <slot></slot>
    <p v-if="errMessage">{{errMessage}}</p>
  </div>
</template>

<script>
import Schema from 'async-validator'
export default {
  name: 'kFormItem',
  inject: ['form'],
  props: {
    label: {
      type: String,
      default: ''
    },
    prop: {
      type: String
    }
  },
  data () {
    return {
      errMessage: ''
    }
  },
  mounted () {
    this.$on('validate', () => { this.validate() })
  },
  methods: {
    validate () {
      // 做校验
      const value = this.form.model[this.prop]
      const rules = this.form.rules[this.prop]
      const desc = { [this.prop]: rules }
      const schema = new Schema(desc)
      return schema.validate({ [this.prop]: value }, error => {
        if (error) {
          this.errMessage = error[0].message
        } else {
          this.errMessage = ''
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

In k-form-itemwill be form validation and error message display component. But modeland rulesare blocked in the k-formassembly, I used here provideand injectwere passaged value between components in k-form-itemcan get validation rules component using async-validator check the library for verification.

k-form

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'kForm',
  provide () {
    return {
      form: this
    }
  },
  props: {
    model: {
      type: Object
    },
    rules: {
      type: Object
    }
  },
  methods: {
    validate (cb) {
      const tasks = this.$children
        .filter(item => item.prop)
        .map(item => item.validate())
      Promise.all(tasks)
        .then(() => cb(new Error(true)))
        .catch(() => {
          const flag = false
          cb(flag)
        })
    }
  }
}
</script>

<style lang="scss" scoped></style>

k-formForm provides a validatemethod of checking whether it is through the check form. Using k-formthe form, Register or Log in judgment when it entry form is correct

Renderings

Here Insert Picture Description

to sum up

  • Use of technology to the point
    • Between components by value
      • props, Parent component subassembly to pass through properties
      • $emit, Sub-assemblies through the distribution of events by value, parent component to monitor received value, it can also be used this.$onandthis.$parent.$emit
      • provideAnd injectcommunication between the ancestor and descendant component assembly
    • slotReference slot
    • v-modelTwo-way data binding implementation
    • Promise.allusage of
    • async-validatorUsing a checksum library
  • Component design, first try to use this to write a shelf components, then the communication connection between the components of the various components of how you use components individually to implement the various components, a clear function of the individual components by
Published 17 original articles · won praise 0 · Views 402

Guess you like

Origin blog.csdn.net/k19970320j/article/details/104387186