如何封装一个带表单验证的 Vue的表单插件(一):起步

缘起

以前做Vue项目,经常需要用到表单验证,当时为了项目的速度,为了更好的交互和上线之后更稳定的性能,一直使用的都是
VeeValidate
确实很好用很强大,但是复杂的英文API的确也在开发中给我带了一定的困难,再加上项目上的需求或多或少和插件有一点点的差别,去看源码修改插件这种事情对我这个菜鸟压力太大~~;一直痛并快乐着。

在闲鱼时间,一直希望可以系统学习一下如何封装一个form表单插件,一方面解决工作上面的痛点,一方面可以牢固所学知识。

??????????????????????????????????????????????????????????

效果

下面的动图就是我最近学习写出来的效果,功能简单,但也因此,容易应对不通项目需求更快速的做出适当定制~
在这里插入图片描述

分析与准备

form表单组件属于基础组件(不包含任何业务逻辑 只包含某种独立功能的组件,比如模态框、日历插件也是基础组件,这种组件适用于大多数项目,通过高度抽象的API 和可定制化选项匹配大多数项目

所以说,我们不能在form表单组件里面出现业务逻辑,它要适用于绝大多数的需要表单校验的地方,在这个表单组件里,我们使用 异步表单验证插件 async-validator。很多大型的UI框架都是使用这个插件,使用比较简单,大家可以直接去GitHub上面查看使用文档。

拆分

封装一个基础组件,一定要记住一个词 单一职责,就是一个组件模块做一件事,如果功能不同职责不一一定要再次拆开,这样可以减少代码耦合,增加组件的可复用性,逻辑更加清晰。

下面我们进入正题,我们将组件整个form表单组件分为三个部分:

  • 表单元素组件,也就是input、textarea、select这些原生HTML标签,组件的主要功能是接受父级传入的值并将自身改变的值传到父组件(也就是双向数据绑定),另外将触发校验的事件传给外面的监听器,将value作为回调函数的参数。
  • form-item组件,独立的表单校验组件,此组件监听表单元素组件的触发校验的事件,获取当前用户设置的校验规则以校验的值(只是当前form-item)。设置表单校验的状态和报错信息。简而言之,表单的验证工作就是又form-tem组件完成。
  • form组件,作为全部校验的功能组件,form表单通常会有一个提交按钮,可以出发整个表单的校验工作。

简单分析完了我们即将详细讲解的几个组件,接下来我们提前分析几个特殊的功能函数,在一般写Vue 项目中我们很少用上的,但是在基础组件中,非常实用的几个工具函数。

工具函数(方法)

1、 首先我们说的第一个方法是 dispatch,作用是向上指定组件暴露事件 以供监听,不限层级,直到找到为止,代码如下:

export default {
  methods: {
	dispatch (componentName, eventName, params) {
     let parent = this.$parent || this.$root
      let name = parent.$options.name
      while (parent && (name !== componentName)) {
        parent = parent.$parent
        if (parent) {
          name = parent.$options.name
        }
      }
      parent.$emit(eventName, params)
   	 }
    }

方法接受三个参数:

  • componentName 指定的向上组件name值(提倡每个.vue文件都要有自己的专属name)
  • eventName 上级监听的事件名
  • params 事件回调的值

2、 第二个方法是 capture,作用是向下指定组件暴露事件 以供监听,不限层级,直到找到为止,代码如下:

function loops (childrens, componentName, eventName, params) {
  for (let child of childrens) {
    let name = child.$options.name
    if (name && name !== componentName) {
      loops(child.$children, componentName, eventName, params)
    } else {
      child.$emit(eventName, params)
    }
  }
  export default {
	  methods: {
  		capture (componentName, eventName, params) {
		 	let childrens = this.$children
   		 	loops(childrens, componentName, eventName, params)
   		}
	  }

方法接受三个参数:

  • componentName 指定的向下的组件name值(提倡每个.vue文件都要有自己的专属name)
  • eventName 子级监听的事件名
  • params 事件回调的值

之所以用到这两个方法,是因为我们的form的三个基础组件之间并不一定是紧密相连的父子组件关系,用户还可能在其中嵌套其他组件,在这种情况下我们不能限制用户的组件嵌套方式。

3、另外我们还要用到

  • 向上查找最近的最近的指定组件 findComponentUpward
  • 向下查找所有指定的组件 findComponentsDownward
// 向上寻找指定name的组件
function findComponentUpward (context, componentName) {
  let parent = context.$parent
  if (!parent) {
    return
  }
  let name = parent.$options.name
  if (name === componentName) {
    return parent
  } else {
    return findComponentUpward(parent, componentName)
  }
}
export { findComponentUpward }

// 向下寻找指定name的所有组件

function findComponentsDownward (context, componentName) {
  return context.$children.reduce((components, child) => {
    if (child.$options.name === componentName) components.push(child)
    const foundChilds = findComponentsDownward(child, componentName)
    return components.concat(foundChilds)
  }, [])
}
export { findComponentsDownward }
现在我们前期的准备工作基本完成了,接下来我们要开始真正的form表单组件编写了~~
备注

源码地址: https://github.com/wangyangsea/wy-validate

参考文章

Vue.js 组件精讲

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来为你介绍如何使用 Vue 封装一个步骤表单。 1. 创建一个步骤表单组件 首先,我们需要创建一个步骤表单组件,可以使用 Vue 的单文件组件(.vue)来实现,例如: ```vue <template> <div class="step-form"> <div class="step-header"> <div v-for="(step, index) in steps" :key="index" class="step-item"> <div class="step-number">{{ index + 1 }}</div> <div class="step-title">{{ step.title }}</div> </div> </div> <div class="step-content"> <slot :step="currentStep"></slot> </div> <div class="step-footer"> <button @click="prevStep" :disabled="currentStep === 0">上一步</button> <button @click="nextStep" :disabled="currentStep === steps.length - 1">下一步</button> <button @click="submitForm" v-if="currentStep === steps.length - 1">提交</button> </div> </div> </template> <script> export default { name: 'StepForm', props: { steps: { type: Array, required: true } }, data() { return { currentStep: 0 } }, methods: { nextStep() { this.currentStep++ }, prevStep() { this.currentStep-- }, submitForm() { // 提交表单的逻辑 } } } </script> <style scoped> .step-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .step-item { display: flex; align-items: center; } .step-number { width: 30px; height: 30px; border-radius: 50%; background-color: #ccc; color: #fff; display: flex; justify-content: center; align-items: center; margin-right: 10px; } .step-title { font-size: 16px; font-weight: bold; } .step-content { margin-bottom: 20px; } .step-footer { display: flex; justify-content: space-between; } </style> ``` 2. 使用步骤表单组件 在需要使用步骤表单的页面中,可以像使用其他组件一样使用步骤表单组件: ```vue <template> <div> <step-form :steps="steps"> <template v-slot="{ step }"> <div v-if="step === 0"> <!-- 第一步的表单 --> </div> <div v-if="step === 1"> <!-- 第二步的表单 --> </div> <div v-if="step === 2"> <!-- 第三步的表单 --> </div> </template> </step-form> </div> </template> <script> import StepForm from './StepForm.vue' export default { components: { StepForm }, data() { return { steps: [ { title: '第一步' }, { title: '第二步' }, { title: '第三步' } ] } } } </script> ``` 在步骤表单组件中,我们使用了插槽(slot)来实现不同步骤对应的表单内容。在使用步骤表单组件时,需要传入一个 steps 属性,该属性是一个包含每个步骤的标题的数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值