【小試牛刀】手寫一個form表單,實現校驗功能

參照element ui 表單組件,實現一個簡易的登錄表單校驗。
App.vue

<template>
  <div id="app">
    {{value}}
    <k-input :value="value" @input="setVal"></k-input>
    <hr/>
    <k-form :model="userInfo" :rules="rules">
      <k-form-item label="用戶名" prop="username">
        <k-input v-model="userInfo.username"></k-input>
      </k-form-item>
      <k-form-item label="密碼" prop="password">
        <k-input v-model="userInfo.password" type="password"></k-input>
      </k-form-item>
    </k-form>
  </div>
</template>

<script>
import kInput from "./components/Input.vue";
import KFormItem from "./components/FormItem.vue";
import KForm from "./components/Form.vue";

export default {
  name: "app",
  components: {
    kInput,
    KFormItem,
    KForm
  },
  data() {
    return {
      value: "gg",
      userInfo: {
        username: "",
        password: ""
      },
      rules: {
        username: [
          { required: true, message: "請輸入用戶名" },
          { min: 3, max: 5, message: "長度在 3 到 5 個字符" }
        ],
        password: [{ required: true, message: "請輸入密碼" }]
      }
    };
  },
  methods: {
    setVal(val) {
      this.value = val;
    }
  }
};
</script>

Input.vue

<!-- input -->
<template>
  <div>
    <input :type="type" :value="value" @input="onInput" />
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: String
    },
    type: {
      type: String,
      default: "text"
    }
  },
  components: {},

  data() {
    return {};
  },

  computed: {},

  methods: {
    onInput(e) {
      let value = e.target.value;
      this.$emit("input", value);
      this.$parent.$emit("validate")
    }
  }
};
</script>
<style lang='less' scoped>
</style>

FormItem.vue

<!-- FormItem -->
<template>
  <div>
    <label :prop="prop">{{label}}</label>
    <slot></slot>
    <p v-if="errorStatus">{{errorMsg}}</p>
  </div>
</template>

<script>
import  Schema  from "async-validator";
export default {
  props: {
    label: {
      type: String
    },
    prop: {
      type: String
    }
  },
  inject: ["Form"],
  components: {},

  data() {
    return {
      errorStatus: false,
      errorMsg: ""
    };
  },

  mounted() {
    this.$on("validate",this.validator);
  },

  methods: {
    validator() {
      let rules = this.Form.rules[this.prop];
      let value = this.Form.model[this.prop];
      let descriptor = { [this.prop]: rules };
      let schema = new Schema(descriptor);
      schema.validate({[this.prop]:value},errors=>{
        if(errors){
          this.errorStatus = true;
          this.errorMsg = errors[0].message
        }else{
          this.errorStatus = false;
          this.errorMsg = ""
        }
      })
    }
  }
};
</script>
<style lang='less' scoped>
</style>

Form.vue

<!-- Form -->
<template>
  <div>
    <form :model="model" :rules="rules">
      <slot></slot>
    </form>
  </div>
</template>

<script>
export default {
  props: {
    model: {
      type: Object,
      required: true
    },
    rules: Object
  },
  provide() {
    return {
      Form: this
    };
  },
  components: {},

  data() {
    return {};
  },

  computed: {},

  methods: {}
};
</script>
<style lang='less' scoped>
</style>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章