写自己的表单组件
读书笔记:跑起来的车更容易转向,我们中很多人都坐在自己生活的“车库”里,坐在停着的汽车里,拼命的转动方向,若果起初方向就错啦,不启动的车是没有办法回到正确的方向上。当你发动它,你至少在某个方向上前进着,一旦车处于运动状态,你就可以轻松的掌控你手中的方向盘,即使当前方向是错的,也能很容易的调整到对的轨道上。
element-ui
element-ui强大的功能令我方程序员(vue)爱不释手,用的时候,你是否想过,别人是怎么能实现这么一个强大的ui库。接下来将展示一个手写的组件。
项目的前期工作
- 项目初始化: vue create
- 安装element: vue add element || npm install element
- 启动项目:npm run serve
表单组件
mInput.vue
<!--使用-->
<m-input :value="model.username" @input="model.username = arguments[0]"></m-input>
<!--实现-->
<template>
<div>
<input :type="type" :value="value" @input="onInput">
</div>
</template>
与触发父级传过来的方法,将值传出去,
<script>
export default {
methods: {
onInput(e) {
let value = e.target.value
this.$emit("input", value)
}
}
}
</script>
当input输入时,会触发父级传过来的input事件,改变main.vue的model数据,同时也会触发校验(mFormItem中的检验)
<!--通过触发父级emit,父级自己监听 on -->
onInput(e) {
this.$parent.$emit("validate", value)
}
mFormItem.vue
<!--使用-->
<m-form-item label = "用户名" prop = "username">
<m-input :value="model.username" @input="model.username = arguments[0]"></m-input>
</m-form-item>
<!--实现-->
<template>
<div>
<label for="">{{label}}</label>
<div>
<slot></slot>
<p v-if = "errStatus">{{errMessage}}</p>
</div>
</div>
</template>
<script>
<!--借用element的校验器-->
import Schema from 'async-validator'
export default {
inject: ["kForm"],
props: ["label", "prop"],
data() {
return {
errMessage: '',
errStatus: false
}
},
mounted() {
this.$on("validate", this.validate)
},
methods: {
validate() {
const rules = this.kForm.rules[this.prop]
const value = this.kForm.model[this.prop]
let descripte = {[this.prop]: rules}
let schema = new Schema(descripte)
schema.validate({[this.prop]: value}, errors => {
if (errors) {
this.errMessage = errors[0].message
this.errStatus = true
}else{
this.errMessage = ""
this.errStatus = false
}
})
}
}
}
</script>
mForm.vue
<!--使用-->
<m-form :model = "model" :rules = "rules">
<m-form-item label = "用户名" prop = "username">
<m-input :value="model.username" @input="model.username = arguments[0]"></m-input>
</m-form-item>
</m-form>
<!--实现-->
<template>
<form>
<slot></slot>
</form>
</template>
mFrom 作为最外层的容器,其绑定了检验的规则和数据,如何传递给里面的子孙级进行相应的校验
<script>
export defalut{
provie(){
return {
mForm: this
}
}
}
</script>
<!--配合inject获取-->
main.vue
<!--所需的数据-->
<script>
export default {
data() {
return {
model: {
username: "",
password: ""
},
rules: {
username: [{
required: true,
message: "请输入用户名"
}],
password: [{
required: true,
message: "请输入密码"
}]
}
}
}
}
</script>
整体思考几个问题
- minput是自定义组件,如何实现对父级数据的双向数据绑定
- mFormItem如何执行校验?如何知道input状态?怎么获取对应的数据?
- Form是如何做全局校验,用什么方法将数据模型和校验规则传递给内部的组件?
答案
- mInput: 里的input通过触发穿过来的input事件,以及让mFormItem
自己触发身上的事件,并将值传递出去
this.$parent.$emit("validate", value) - mFormItem: 引用element的底层校验器async-validator,当组件挂载时监听自己在mInput上触发的方法:
this.$on("validata", this.validate), 用inject获取Form传递过来的规则和数据模型。 - Form: props接收model, rules, 利用provide将自己当参数传递给底层组件使用自己上面的数据。
以上是今日分享,希望有误的地方,欢迎大家提出来。喜欢的话可以点赞,更多的个人分享将陆续码出来。