zoukankan      html  css  js  c++  java
  • vue手写elform组件

    index.vue

    <template>
      <div>
        <s-form :model="model" :rules="rules" ref="loginForm">
          <s-form-item label="用户名" prop="username">
            <s-input v-model="model.username"></s-input>
          </s-form-item>
          <s-form-item label="密码" prop="password">
            <s-input v-model="model.password" type="password"></s-input>
          </s-form-item>
          <s-form-item>
              <button @click="onLogin">登录</button>
          </s-form-item>
        </s-form>
        {{model}}
      </div>
    </template>
    
    <script>
    import SInput from "./SInput.vue";
    import SFormItem from "./SFormItem.vue";
    import SForm from "./SForm.vue";
    
    export default {
      components: {
        SInput,
        SFormItem,
        SForm
      },
      data() {
        return {
          model: {
            username: "tom",
            password: ""
          },
          rules: {
            username: [{ required: true, message: "用户名必填" }],
            password: [{ required: true, message: "密码必填" }]
          }
        };
      },
      methods: {
          onLogin() {
              this.$refs.loginForm.validate((isValid) => {
                  if (isValid) {
                      alert('登录!!!')
                  } else {
                      alert('有错!!')
                  }
              })
          }
      },
    };
    </script>

    SForm.vue

    <template>
      <div>
        <slot></slot>
      </div>
    </template>
    
    <script>
    export default {
      provide() {
        return {
          form: this // 传递Form实例给后代,比如FormItem用来校验
        };
      },
      props: {
        model: {
          type: Object,
          required: true
        },
        rules: {
          type: Object
        }
      },
      methods: {
        validate(cb) {
          // map结果是若干Promise数组
          const tasks = this.$children
            .filter(item => item.prop)
            .map(item => item.validate());
          //   所有任务必须全部成功才算校验通过
          Promise.all(tasks)
            .then(() => cb(true))
            .catch(() => cb(false));
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    </style>

    SFormItem.vue

    <template>
      <div>
        <label v-if="label">{{label}}</label>
        <slot></slot>
        <!-- 校验信息 -->
        <p v-if="errorMessage">{{errorMessage}}</p>
      </div>
    </template>
    
    <script>
    import Schema from "async-validator";
    
    export default {
      data() {
        return {
          errorMessage: ""
        };
      },
      inject: ["form"],
      props: {
        label: {
          type: String,
          default: ""
        },
        prop: String
      },
      mounted() {
        // 监听校验事件、并执行监听
        this.$on("validate", () => {
          this.validate();
        });
      },
      methods: {
        validate() {
          // 执行组件校验
          // 1.获取校验规则
          const rules = this.form.rules[this.prop];
    
          // 2.获取数据
          const value = this.form.model[this.prop];
    
          // 3.执行校验
          const desc = {
            [this.prop]: rules
          };
          const schema = new Schema(desc);
          //   参数1是值,参数2是校验错误对象数组
        //   返回的Promise<boolean>
          return schema.validate({ [this.prop]: value }, errors => {
            if (errors) {
              // 有错
              this.errorMessage = errors[0].message;
            } else {
              // 没错,清除错误信息
              this.errorMessage = "";
            }
          });
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    </style>

    SInput.vue

    <template>
        <div>
            <!-- 自定义组件要实现v-model必须实现:value, @input -->
            <!-- $attrs存储的是props之外的部分 -->
            <!-- {type:'password'} -->
            <input :value="value" @input="onInput" v-bind="$attrs">
        </div>
    </template>
    
    <script>
        export default {
            inheritAttrs: false, // 避免顶层容器继承属性
            props: {
                value: {
                    type: String,
                    default: ''
                }
            },
            methods: {
                onInput(e) {
                    // 通知父组件数值变化
                    this.$emit('input', e.target.value);
    
                    // 通知FormItem校验
                    this.$parent.$emit('validate');
                }
            },
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
  • 相关阅读:
    PHP基础学习笔记(一)
    安装wampserver之后,浏览器中输入localhost页面显示IIS7解决办法
    HTML5常识总结(一)
    AngularJs中的服务
    AngularJs中的directives(指令part1)
    Happy Number——LeetCode
    Binary Tree Zigzag Level Order Traversal——LeetCode
    Construct Binary Tree from Preorder and Inorder Traversal——LeetCode
    Construct Binary Tree from Inorder and Postorder Traversal——LeetCode
    Convert Sorted Array to Binary Search Tree——LeetCode
  • 原文地址:https://www.cnblogs.com/cupid10/p/15617599.html
Copyright © 2011-2022 走看看