Form组件的开发 | 青训营笔记

106 阅读2分钟

这是我参与「 第五届青训营 」伴学笔记创作活动的第 6 天

Form组件的开发

一、基本功能

1、数据校验,给用户正确或错误反馈

2、表单项:FormItem

二、样式编写

1、labelSize:改变表单的长度,提供sm、md、lg三种宽度选择

2、labelAlign:改变表单位置,start、center、end分别表示靠左、居中、靠右

三、表单校验

1、安装依赖

yarn add async-validator -S

2、创建input组件实现数据双向绑定触发校验、状态反馈和图标等

setup(props: InputProps, { emit }) {
    // 注入校验方法
    const formItem = inject('FORM_ITEM_CTX') as FormItemContext
    const onInput = (e: Event) => {
      const val = (e.target as HTMLInputElement).value
      emit('update:modelValue', val)
      formItem.validate()
    }
  }
})

3、这个Input的作用:

  • 接收modelValue以及type绑定到内部的input当中

  • 注入校验方法formItem

  • 拿到当前input的value发送出去emit('update:modelValue', val)

  • 执行校验方法

4、校验

  • 当用户不需要校验时,应该默认返回true

  • 存在四种情况:用户没有在表单中使用formItem、用户没有设置field、用户没有定义rules、定义了rules没有field

if (!formCtx) {
  // formItem没有在表单中使用
  console.warn('请在Form中使用FormItem')
  return Promise.reject('请在Form中使用FormItem')
}
if (!props.field) {
  console.warn('如果要校验当前项,请设置field字段')
  return Promise.reject('如果要校验当前项,请设置field字段')
}
// 不需要校验
if (!formCtx.rules) {
  return Promise.resolve({ result: true })
}
const itemRules = formCtx.rules[props.field] || undefined
if (!itemRules) {
  return Promise.resolve({ result: true })
}
  • 当用户需要校验时,获取校验规则和数值,使用Validator工具进行校验

// 获取校验规则和数值
const value = formCtx.model[props.field]
// 执行校验返回结果
const validator = new Validator({ [props.field]: itemRules })
return validator.validate({ [props.field]: value }, errors => {
if (errors) {
// 校验失败
showMessage.value = true
errorMessage.value = errors[0].message || '校验错误'
} else {
// 校验通过 清空
showMessage.value = false
errorMessage.value = ''
}
})

5、全局校验

  • 想要点击某个按钮,比如登录,就自动调用校验方法进行校验

  • 现存放待校验的items(Set)

const formItems = new Set<FormItemContext>()
  • 如果有field就添加到数组中,否则不,所以需要定义添加和删除函数

const addItem = (item: FormItemContext) => formItems.add(item)
const removeItem = (item: FormItemContext) => formItems.delete(item)
  • 挂载后注册到formCtx中

// 挂在后注册到formCtx中
onMounted(() => {
  if (props.field) {
  formCtx?.addItem(formItemCtx)
	}
})
onUnmounted(() => {
  if (props.field) {
  formCtx?.removeItem(formItemCtx)
	}
})
  • 将validate提供给后代使用,定义参数valid,如果有就成功否则校验失败,在使用的vue中

const onLogin = () => {
    loginForm.value.validate(valid => {
      if (valid) {
        alert('登录成功')
      } else {
        alert('校验失败,请重试!')
      }
    })
  }