关于javascript:高仿一个element的form组件

37次阅读

共计 1722 个字符,预计需要花费 5 分钟才能阅读完成。

实现 elementui 的 form 组件

指标实现

  • 实现 element 的表单绑定和校验
  • 回顾 vue 组件传值的形式
  • 学习 promise 的源码实现
  1. EInput 组件

<template>
  <div>
      // 应用 v -bind="$attrs" 让子组件继承父组件所有的属性,这样子组件就不必承受父组件传入的值
      // 如 type,pleaseholder 等属性
    <input :value="valueInInput" @input="handleInput" v-bind="$attrs" />
  </div>
</template>

<script>
export default {
  name: 'EInput',
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      // 保障单项数据流
      valueInInput: this.value
    }
  },
  methods: {handleInput (e) {
      this.valueInInput = e.target.value;
      this.$emit('input', this.valueInInput)
    }
  }

}
</script>

<style>
</style>
  1. EFromItem 组件
  • 装置 async-validator,用于表单的验证
<template>
  <div>
    <label v-if="label">{{label}}</label>
    <slot></slot>
    <p v-if="errorMessage" class="error">{{errorMessage}}</p>
    <!-- {{form.rules}} -->
  </div>
  
</template>

<script>
import Schema from 'async-validator'
// import {error} from 'shelljs/src/common';
export default {
   // 承受父组件的传入
  inject: ['form'],
  name: 'EFormItem',
  props: {
    label: {
      type: String,
      default: ''
    },
    prop: {type: String}
  },
  data () {
    return {errorMessage: ''}
  },
  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 }, errors => {if (errors) {this.errorMessage = errors[0].message
        } else {this.errorMessage = ''}
      })
    }
  }

}
</script>

<style scoped>
.error {color: red;}
</style>
  1. EFrom 组件
  • 应用 provide 传入一个 form 的值,这个值会把 form 所有的属性全副存入
  • validate 提供一个返回的 promise 的汇合
<template>
  <div>
    <slot></slot>
  </div>
</template>

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

<style>
</style>

正文完
 0