element ui左右布局容器 elementui表单布局_element ui左右布局容器


组件化思想


element ui左右布局容器 elementui表单布局_element ui表单必填_02


第三方组件应用

  • Element-UI:http://element-cn.eleme.io/
  • element集成:vue add element
  • 组件使用:创建一个登陆表单并可以校验用户输入
<template>
 <div>
  <h3>Element表单</h3>
    <hr>
    <el-form :model="model" :rules="rules" ref="loginForm">
     <el-form-item label="用户名" prop="username">
      <el-input v-model="model.username" autocomplete="off"></el-input>
     </el-form-item>
     <el-form-item label="确认密码" prop="password">
      <el-input type="password" v-model="model.password" autocomplete="off">
  </el-input>
     </el-form-item>
     <el-form-item>
      <el-button type="primary" @click="submitForm('loginForm')">提交</el-
  button>
     </el-form-item>
    </el-form>
   </div>
</template>
<script>
export default {
 data() {
  return {
   model: { username: "tom", password: "" },
   rules: {
    username: [{ required: true, message: "请输入用户名" }],
    password: [{ required: true, message: "请输入密码" }],
  }
 };
},
 methods: {
   submitForm(form) {
     this.$refs[form].validate(valid=>{
       if (valid) {
         alert('请求登录!')
      } else {
         alert('校验失败!')
      }
    })
  }
},
};
</script>


  • 使用时我们要先导入Form、FormItem、Input
  • import { Button,Form,FormItem,Input } from 'element-ui'
  • 然后添加到vue实例上Vue.use(Form)、Vue.use(FormItem)、Vue.use(Input)

组件设计:实现Form、FormItem、Input

核心关注:

  1. Form怎么跨组件传数据
  2. FormItem怎么执行校验
  3. Input怎么实现双向绑定

实现Input

  • 任务1:实现input组件双向绑定的功能

v-model是语法糖,实现自定义组件双绑只需要指定:value和@input即可

  • 任务2:值发生变化能够通知FormItem组件
<template>
  <div>
    <input :type="type" :value="value" @input="onInput">
  </div>
</template>
<script>
  export default {
    props: {
      value: {
        type: String,
        default: ''
     },
      type: {
        type: String,
        default: 'text'
     }
   },
    methods: { // input事件触发设置模型的值并通知父组件
      onInput(e) {
        let inputValue = e.target.value;
        this.$emit('input', inputValue);
     }
   },
 }
</script>


实现FormItem


element ui左右布局容器 elementui表单布局_element ui左右布局容器_03


  • 任务1:给Input预留插槽 - slot
  • 任务2:能够展示label和校验信息
  • 任务3:能够进行校验
<template>
 <div>
  <label v-if="label">{{label}}</label>
  <slot></slot>
  <p v-if="error">{{error}}</p>
 </div>
</template>
<script>
export default {
  props: {
    label: {// 输入项标签
      type: String,
      default: ''
   },
   prop: {// 字段名
      type: String,
      default: ''
   },
 },
  data() {
    return {
      error: '' // 校验错误
   }
 },
};
</script>


实现Form

  • 给form-item预留槽位
  • 将数据传递给后代便于它们访问数据模型和校验规则

provide && inject


<template>
 <form>
  <slot></slot>
 </form>
</template>
<script>
export default {
 provide() {
  return {
   form: this // 将组件实例作为提供者,子代组件可方便获取
 };
},
 props: {
  model: { type: Object, required: true },
  rules: { type: Object }
}
};
</script>


数据校验

  • 思路:校验发生在FormItem,它需要知道何时校验(让Input通知它),还需要知道怎么校验(注入校验规则)
onInput(e) {
// ...
// $parent指FormItem
this.$parent.$emit('validate');
}


  • 任务1:Input通知校验
  • 任务2:FormItem监听校验通知,获取规则并执行校验
inject: ['form'], // 注入
mounted(){// 监听校验事件
  this.$on('validate', this.validate)
},
methods: {
  validate() {
      // 获取对应FormItem校验规则
      console.log(this.form.rules[this.prop]);
      // 获取校验值
      console.log(this.form.model[this.prop]);
  }
},


  • 安装async-validator

npm i async-validator -S


import schema from "async-validator";
validate() {
   // 获取对应FormItem校验规则
   const rules = this.form.rules[this.prop];
   // 获取校验值
   const value = this.form.model[this.prop];
   // 校验描述对象
   const descriptor = { [this.prop]: rules };
   // 创建校验器
   const schema = new Schema(descriptor);
   schema.validate({ [this.prop]: value }, errors => {
    if (errors) {
     // 将错误信息显示
     this.error = errors[0].message;
   } else {
     // 校验通过
     this.error = "";
   }
  });
}


运行结果


element ui左右布局容器 elementui表单布局_element ui左右布局容器_04


console.log 加 debugger 找到原因
prop="username"
FormItem缺少这个属性,就会导致上面错误出现。
主要是代码实现的不够健壮,没有对校验进行兜底处理。

结语

搬砖的时候有时我会碰到一种状态:着相。陷入自己的模式里无法自拔,进入一种死循环的状态,很明显的错误却发现不了。这种时候寻求队友帮忙换一种思路,或者出去透气把自己解脱出来,可能就会豁然开朗。

使用vue组件化时候,难免也会带有个人色彩,可能与个人经验和思考方式有关系。这种情况我觉得不是减少或者避免,而是需要优化。

只要自己看过足够多的好架构、好设计,自然会不断的借鉴靠近他们,慢慢地自己思想会跟着提升,然后在实践中应用,验证。