vue Component Development - a simple simulation of the form element-ui form, the whole sentence prompts alert, tree assembly

 (A) Form analog form:

1. Create AForm.vue components:

<template>
    <div class="a-form">
        <slot></slot>
    </div>
</template>
<script>
    export default{
      name:"AForm",
      provide(){  //祖先向后代组件传值,将整个祖先组件this传递给后代,后代用inject:["form"]就可以接受祖先组件传递过来的值了
        return{
          form:this
        }
      },
      props:{
        model:{
          type:Object,
          require:true
        },
        rules:[Object]
      }
    }
</script>
<style lang="less" scoped>

</style>

2. Create AFormItem.vue components:

<template>
    <div class="a-form-item">
      <div class="item-box">
        <label v-if="label" class="item-box-label">{{label}}</label>      
        <slot></slot>
      </div>
      <p v-if="errMessage">{{errMessage}}</p>
    </div>
</template>
<script>
    export default{
      inject:["form"], //后代接受祖先传递过来的form参数值
      name:"AFormItem",
      props:{
        label:{
          type:String,
          default:""
        },
        prop:{
          type:String,
          default:""
        }
      },
      data(){
        return{
          errMessage:""
        }
      },
      mounted(){
        this.$on("validate",this.validateHandle)
      },
      methods:{
        validateHandle(val){ //校验这个prop是否满足rules里面的,如果满足就errMessage='',否则errMessage='报错信息'
          this.form.rules[this.prop]
        }
      }
    }
</script>
<style lang="less" scoped>
.a-form-item{
  padding: 10px 0;
}
.item-box{
  display: flex;
  justify-content: flex-start;
  flex-direction: row;
  align-items: center;
  .item-box-label{
    width: 80px;
  }
}
</style>

3. Create AInput.vue components:

<template>
    <div class="a-input">
        <input  v-bind='$attrs' :value="value" @input="onInput"/>
    </div>
</template>
<script>
    export default{
        name:"AInput",
        inheritAttrs:false, //为true时,默认 直接挂在在父组件<a-input type="text" placeholder="请输入"></a-input>
                            // 的type="text" placeholder="请输入"属性会被挂载在<div class="a-input"/>上 
        props:{
            value:{
                type:String,
                default:""
            }
        },
        methods:{
            onInput(e){
                let val=e.target.value
                this.$emit("input",val);
                this.$parent.$emit("validate",val)
            }
        }
    }
</script>
<style lang="less" scoped>

</style>

4. called home.vue component:

<template>
  <div class="home">
    <a-form :model='form' :rules='rules'>
      <a-form-item label="密码1" prop="user">
        <a-input type="text" v-model="form.user" autocomplete="off"  placeholder="请输入密码"></a-input>
      </a-form-item>
      <a-form-item >
        <button>提交</button>
      </a-form-item>
    </a-form>
  </div>
</template>

<script>
import AForm from "@/components/AForm/AForm.vue"
import AFormItem from "@/components/AForm/AFormItem.vue"
import AInput from "@/components/AForm/AInput.vue"
export default {
  name: 'home',
  components:{
    AForm,
    AFormItem,
    AInput
  },
  data(){
    return{
      form:{
        user:'123'
      },
      rules:{

      }
    }
  }
}
</script>

Note: vue knowledge will be used:

          1. v-model的原理:<input :value="value"  @input='inputHandle' />。

          2. provide and inject: ancestor component values ​​to the next generation components pass.

          4. inheritAttrs and $ attrs properties: detail with reference https://blog.csdn.net/qq_42231156/article/details/103934991 .

          5. slot slots: Reference https://blog.csdn.net/qq_42231156/article/details/103927760 .

          6. $ on $ emit and event delivery:


 

 

 

 

 

He published 193 original articles · won praise 36 · Views 100,000 +

Guess you like

Origin blog.csdn.net/qq_42231156/article/details/103936870