仿ElementUI实现一个Form表单的实现代码(2)

<template> <div> <!-- 解释一 --> <label v-if="label">{{ label }}</label> <div> <!-- 解释二 --> <slot></slot> <!-- 解释三 --> <p v-if="validateState === 'error'">{{ validateMessage }}</p> </div> </div> </template> <script> export default { name: "EFormItem", props: { label: { type: String, default: '' }, prop: { type: String, default: '' } }, data() { return { validateState: '', validateMessage: '' } }, } </script> <style scoped> .error { color: red; } </style>

和上面一样,我们接着对上面的代码进行一些解释:

**解释一:**根据 ElementUI 中的用法,我们知道 label 是父组件传来,且当传入时我们展示,不传入时不展示。

解释二: slot 是一个预留的槽位,我们可以在其中放入 input 或其他组件、元素。

解释三: p 标签是用来展示错误信息的,如果验证状态为 error 时,就显示。

此时,我们的 FormItem 组件也可以使用了。同样,我们在 App.vue 中引入该组件。

<template> <div> <e-form-item label="用户名" prop="name"> <e-input v-model="ruleForm.name"></e-input> </e-form-item> <e-form-item label="密码" prop="pwd"> <e-input v-model="ruleForm.pwd"></e-input> </e-form-item> <div> {{ ruleForm }} </div> </div> </template> <script> import EInput from './components/Input.vue'; import EFormItem from './components/FormItem.vue'; export default { name: "app", components: { EInput, EFormItem }, data() { return { ruleForm: { name: '', pwd: '', }, }; }, }; </script>

仿ElementUI实现一个Form表单的实现代码

 

3. Form 的设计

到现在,我们已经完成了最内部的 input 以及中间层的 FormItem 的设计,现在我们开始设计最外层的 Form 组件。

当层级过多并且组件间需要进行数据传递时,Vue 为我们提供了 provide 和 inject API,方便我们跨层级传递数据。

我们举个例子来简单实现一下 provide 和 inject 。在 App.vue 中,我们提供数据(provide)。

export default { name: "app", provide() { return { msg: '哥是最外层提供的数据' } } }; </script>

接着,我们在最内层的 Input.vue 中注入数据,观察结果。

<template> <div> <!-- 1、绑定 value 2、响应 input 事件--> <input type="text" :value="valueInInput" @input="handleInput"> <div>{{ msg }}</div> </div> </template> <script> export default { name: "EInput", inject: [ 'msg' ], props: { value: { type: String, default: '', } }, data() { return { valueInInput: this.value }; }, methods: { handleInput(event) { this.valueInInput = event.target.value; this.$emit('input', this.valueInInput); } }, }; </script>

仿ElementUI实现一个Form表单的实现代码

根据上图,我们可以看到无论跨越多少层级, provide 和 inject 可以非常方便的实现数据的传递。

理解了上面的知识点后,我们可以开始设计 Form 组件了。

<el-form :model="ruleForm" :rules="rules" ref="loginForm"> </el-form>

根据 ElementUI 中表单的用法,我们知道 Form 组件需要实现以下功能:

提供数据模型 model;

提供校验规则 rules;

提供槽位,里面放我们的 FormItem 等组件;

根据上面的需求,我们创建一个 Form.vue 组件:

<template> <form> <slot></slot> </form> </template> <script> export default { name: 'EForm', props: { // 解释一 model: { type: Object, required: true }, rules: { type: Object } }, provide() { // 解释二 return { eForm: this // 解释三 } } } </script>

解释一:该组件需要用户传递进来一个数据模型 model 进来,类型为 Object 。 rules 为可传项。

解释二:为了让各个层级都能使用 Form 中的数据,需要依靠 provide 函数提供数据。

解释三:直接将组件的实例传递下去。

完成了 Form 组件的设计,我们在 App.vue 中使用一下:

<template> <div> <e-form :model="ruleForm" :rules="rules"> <e-form-item label="用户名" prop="name"> <e-input v-model="ruleForm.name"></e-input> </e-form-item> <e-form-item label="密码" prop="pwd"> <e-input v-model="ruleForm.pwd"></e-input> </e-form-item> <e-form-item> <button>提交</button> </e-form-item> </e-form> </div> </template> <script> import EInput from './components/Input.vue'; import EFormItem from './components/FormItem.vue'; import EForm from "./components/Form"; export default { name: "app", components: { EInput, EFormItem, EForm }, data() { return { ruleForm: { name: '', pwd: '', }, rules: { name: [{ required: true }], pwd: [{ required: true }] }, }; }, }; </script>

仿ElementUI实现一个Form表单的实现代码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/7fa75722e996016ae681468843dc26d2.html